# Engine test: priority windows (lifo_stack resolution, costs paid on play, cancelling a spell
# on the stack). Switching resolution to immediate should leave nothing to counter.
game: spell-duel
label: Spell duel (test)
num_players: 2
mode: competitive
description: >
  Test game for priority windows. Player 1 wants to kill player 0's creature (2 life) with two
  shocks (-2 each). Player 0 can make it grow once (+2) or cast a counterspell; player 1 also has
  one counterspell. Everyone has 2 mana. With lifo_stack the last spell cast resolves first and a
  counterspell can cancel something on the stack; with immediate everything resolves at once and
  there is never anything to counter.
constants: {}
state:
  vars:
    life: {scope: global, type: int, init: 2}
    mana: {scope: player, type: int, init_x: "[2, 2]"}
    shocks_left: {scope: global, type: int, init: 2}
    growth_left: {scope: global, type: int, init: 1}
    counters_left: {scope: player, type: int, init_x: "[1, 1]"}
    done: {scope: global, type: bool, init: false}
priority:
  protocol:
    first: player 1 (the attacker)
    first_x: "1"
    order: clockwise_from_first
    closes: all_pass_in_succession
    resolution: lifo_stack
  windows:
    duel: {label: Duel, allows: [fast]}
flow:
  id: root
  kind: sequence
  children:
    - {id: setup, label: Duel, kind: step, do: start, window: duel}
    - {id: outcome, label: Outcome, kind: step, do: finish}
actions:
  start: {effect: []}
  shock:
    speed: fast
    pre_x: "actor == 1 and mana[1] >= 1 and shocks_left > 0"
    cost: [{op: add, var: "mana[1]", amount: -1}, {op: add, var: shocks_left, amount: -1}]
    effect: [{op: add, var: life, amount: -2}]
  grow:
    speed: fast
    pre_x: "actor == 0 and mana[0] >= 1 and growth_left > 0"
    cost: [{op: add, var: "mana[0]", amount: -1}, {op: add, var: growth_left, amount: -1}]
    effect: [{op: add, var: life, amount: 2}]
  counterspell:
    speed: fast
    pre: "mana left, a counterspell left, and an uncancelled spell of the other player on the stack"
    pre_x: "mana[actor] >= 1 and counters_left[actor] > 0 and any(not s['cancelled'] and s['actor'] != actor for s in stack)"
    cost:
      - {op: let, bind: target, value_x: "max(i for i, s in enumerate(stack) if not s['cancelled'] and s['actor'] != actor)"}
      - {op: add, var: "mana[actor]", amount: -1}
      - {op: add, var: "counters_left[actor]", amount: -1}
    effect: [{op: cancel, target_x: target}]
  finish: {effect: [{op: set, var: done, value: true}]}
end:
  - {id: creature_dead, if: "creature dead: player 1 wins", if_x: "life <= 0", result: win, who_x: "1"}
  - {id: creature_alive, if: "window closed and creature alive: player 0 wins", if_x: "done", result: win, who_x: "0"}
