# Engine test: stack order and card instances (draw, look at the top cards, put a card on the
# bottom, shuffle, search with a filter, and per-instance state set with `of_x` + `attr`).
game: stack-game
label: Stack game (test)
num_players: 2
mode: competitive
summary: >
  Test game for stack order and card instances. Players take turns to draw a card, look at the top
  two cards, put a card from their hand on the bottom, shuffle the pile, or search for a card worth
  3 or more. Each drawn card is an instance with its own state (used). After 8 turns, the player
  whose hand is worth the most wins.
constants:
  CARDS: [{id: one, value: 1}, {id: two, value: 2}, {id: three, value: 3}, {id: four, value: 4}, {id: five, value: 5}, {id: six, value: 6}]
  TURNS: 8
state:
  zones:
    pile: {kind: stack, owner: global, visibility: hidden, shuffled: true, init_x: "list(CARDS)"}
    hand: {kind: set, owner: player, visibility: owner}
  vars:
    current: {scope: global, type: ref, init: 0}
    turns: {scope: global, type: int, init: 0}
flow:
  id: game
  kind: loop
  over_x: players
  as: current
  until_x: "turns >= TURNS"
  children:
    - {id: turn, kind: step, actor_x: current, do: [draw, look, to_bottom, shuffle, search]}
actions:
  draw:
    pre_x: "len(pile) > 0"
    effect:
      - {op: draw, from: pile, to: "hand[current]"}
      - {op: add, var: turns, amount: 1}
  look:
    pre_x: "len(pile) > 1"
    effect:
      - {op: look, from: pile, n: 2, bind: top}
      - {op: add, var: turns, amount: 1}
  to_bottom:
    pre_x: "len(hand[current]) > 0"
    effect:
      - {op: choose, options_x: "hand[current]", bind: c}
      - {op: set, of_x: c, attr: used, value: true}
      - {op: move, what_x: c, from: "hand[current]", to: pile, position: bottom}
      - {op: add, var: turns, amount: 1}
  shuffle:
    effect:
      - {op: shuffle, zone: pile}
      - {op: add, var: turns, amount: 1}
  search:
    pre_x: "len(pile) > 0"
    effect:
      - {op: search, from: pile, filter_x: "it['value'] >= 3", bind: c}
      - op: if
        cond_x: "c is not None"
        then:
          - {op: move, what_x: c, from: pile, to: "hand[current]"}
          - {op: shuffle, zone: pile}
      - {op: add, var: turns, amount: 1}
end:
  - id: result
    if_x: "turns >= TURNS"
    result: score
    returns_x: "[(1 if s > o else -1 if s < o else 0) for s, o in [(sum(c['value'] for c in hand[p]), sum(c['value'] for c in hand[1 - p])) for p in players]]"
