# Demonstrates: a campaign of stages, state that carries over (persist), a reset per stage, end
# conditions with a scope that end only the stage, and reading a stage's outcome via results.
game: expedition
label: Expedition
players: "1 player"
num_players: 1
mode: competitive
summary: >
  Three stages in a row. In each stage you must get 3 spaces along before your hunger reaches 3.
  Walk: a die moves you 0, 1, 1 or 2 spaces, and your hunger goes up by 1. Rest: eat 1 ration and
  your hunger drops to 0. Rations and the number of completed stages carry over; position and
  hunger start fresh each stage. Completing a stage earns 1 ration.

constants:
  STAGES: 3
  DISTANCE: 3

state:
  vars:
    rations: {scope: global, type: int, init: 2, persist: campaign}
    completed: {scope: global, type: int, init: 0, persist: campaign}
    played: {scope: global, type: int, init: 0, persist: campaign}
    position: {scope: global, type: int, init: 0}
    hunger: {scope: global, type: int, init: 0}

flow:
  id: journey
  label: Journey
  kind: loop
  until: all stages played
  until_x: "played >= STAGES"
  children:
    - {id: play_stage, label: Stage, kind: subflow, ref: stage}
    - {id: wrap_up, label: Wrap up, kind: step, do: wrap_up}

flows:
  stage:
    id: stage
    label: Stage
    kind: sequence
    children:
      - {id: depart, label: Depart, kind: step, do: depart}
      # No until: the loop runs until an end condition with scope stage ends the subflow.
      - id: days
        label: Days
        kind: loop
        children:
          - {id: day, label: Day, kind: step, actor: traveller, actor_x: "0", do: [walk, rest]}

actions:
  # reset: everything without persist goes back to its initial value (position 0, hunger 0).
  depart: {effect: [{op: reset, scope: stage}]}
  walk:
    effect:
      - {op: roll, die: [0, 1, 1, 2], bind: spaces}
      - {op: add, var: position, amount: spaces, amount_x: spaces}
      - {op: add, var: hunger, amount: 1}
  rest:
    pre: a ration is left
    pre_x: "rations >= 1"
    effect:
      - {op: add, var: rations, amount: -1}
      - {op: set, var: hunger, value: 0}
  # After the subflow, results['stage'] is 'win' or 'loss', set by the end condition with that scope.
  wrap_up:
    effect:
      - op: if
        cond: stage completed
        cond_x: "results.get('stage') == 'win'"
        then:
          - {op: add, var: completed, amount: 1}
          - {op: add, var: rations, amount: 1}
      - {op: add, var: played, amount: 1}

end:
  - {id: arrived, scope: stage, if: "position ≥ distance", if_x: "position >= DISTANCE", result: win}
  - {id: starved, scope: stage, if: "hunger ≥ 3", if_x: "hunger >= 3", result: loss}
  - {id: journey_over, if: "all stages played; payoff = stages completed", if_x: "played >= STAGES", result: score, returns_x: "[completed]"}
