# Worked example from the guide (https://tabletwin.com/docs/guide/): each rule from the rulebook appears below as a comment
# above the piece of model that carries it out.
game: pig
label: Pig
players: "2 players"
num_players: 2
mode: competitive
summary: >
  A push-your-luck dice game. On your turn you roll as often as you like and add the pips to a
  pot. A 1 empties the pot and ends your turn; stopping adds the pot to your score.
  The first player to reach 20 points wins.

# "The first player to reach 20 points wins." Fixed numbers become constants: one place to
# change them, and readable names in the expressions.
constants:
  GOAL: 20

state:
  vars:
    # One score per player: scope player gives a list with one value for each player.
    score: {scope: player, type: int, init: 0}
    pot: {scope: global, type: int, init: 0, note: "points from this turn, not yet safe"}
    current: {scope: global, type: ref, init: 0, note: "loop variable of the turn loop"}
    turn_over: {scope: global, type: bool, init: false}

# "Players take turns until someone wins." A loop over the players without until:
# the game stops through the end condition.
flow:
  id: game
  label: Game
  kind: loop
  over: all players in turn
  over_x: players
  as: current
  order: fixed
  children:
    - id: turn
      label: Turn
      kind: sequence
      children:
        - {id: start, label: Start turn, kind: step, do: start_turn}
        # "Roll as often as you like": a loop that asks each time whether the player rolls or stops.
        - id: rolling
          label: Roll or stop
          kind: loop
          until: turn is over
          until_x: turn_over
          children:
            - {id: choice, label: Roll or stop, kind: step, actor: current player, actor_x: current, do: [roll, stop]}

actions:
  start_turn:
    effect:
      - {op: set, var: pot, value: 0}
      - {op: set, var: turn_over, value: false}
  # "Roll the die. On a 1 the pot is lost and your turn ends. Otherwise add the pips to the pot."
  roll:
    effect:
      - {op: roll, die: [1, 2, 3, 4, 5, 6], bind: pips}
      - op: if
        cond: a 1
        cond_x: "pips == 1"
        then:
          - {op: set, var: pot, value: 0}
          - {op: set, var: turn_over, value: true}
        else:
          - {op: add, var: pot, amount: pips, amount_x: pips}
  # "Stop: the pot goes to your score." Stopping with an empty pot is pointless, so pre makes
  # stopping legal only when the pot holds something. Otherwise rolling is the only option and
  # the engine asks nothing: a single legal action is not a decision.
  stop:
    pre: the pot is not empty
    pre_x: "pot > 0"
    effect:
      - {op: add, var: "score[current]", amount: pot, amount_x: pot}
      - {op: set, var: pot, value: 0}
      - {op: set, var: turn_over, value: true}

end:
  - {id: won, if: "the current player has reached the goal", if_x: "score[current] >= GOAL", result: win, who_x: current}
