note description: "[ The Sequence of Play (SOP) in s {VITP_GAME}, which describes the order of steps in the game and tracks which `player' is currently performing actions. ]" author: "Jimmy J. Johnson" date: "11/11/23" copyright: "Copyright (c) 2023, Jimmy J. Johnson" license: "Eiffel Forum v2 (http://www.eiffel.com/licensing/forum.txt)" class VITP_SEQUENCE_OF_PLAY inherit VITP_ITEM -- GAME_STEP -- rename -- start as step_start, -- forth as step_forth, -- is_before as step_is_before, -- is_after as step_is_after, -- is_off as step_is_off, -- index as step_index redefine make -- player end create make, make_nine_turn feature {NONE} -- Initialization make (a_game: VITP_GAME) -- Create an instance of an eight-turn game. -- (2nd edition rules) do Precursor {VITP_ITEM} (a_game) create turns.make (0) create path.make (0) turns.extend (create {TURN_1}.make (game)) turns.extend (create {TURN_2}.make (game)) -- extend (create {VITP_TURN}.make (game)) -- extend (create {VITP_TURN}.make (game)) -- extend (create {VITP_TURN}.make (game)) -- extend (create {VITP_TURN}.make (game)) -- extend (create {VITP_TURN}.make (game)) -- extend (create {VITP_TURN}.make (game)) ensure then correct_turn_count: turns.count = 2 end make_nine_turn (a_game: VITP_GAME) -- Create an instance of a nine-turn game. do make (a_game) turns.extend (create {TURN_9}.make (game)) end feature -- Access name: STRING = "Sequence of Play" -- The displayable name of Current turn: INTEGER -- The number of the current turn in the sequence of play do -- Search through the `path' for a {TURN_STEP} from path.start until Result > 0 or else path.after loop if attached {VITP_TURN} path.item.node as t then Result := t.turn end path.forth end Result := Result.max (1) end player: like {NATIONALITY_CONSTANTS}.Japanese -- The player to which this step applies do Result := step.player end full_name: STRING -- The string representation of this step. require not_off: not is_off do Result := "" from path.start until path.exhausted loop Result := Result + path.item.node.name if not path.islast then Result := Result + ", " end path.forth end end feature -- Status report is_japanese_player: BOOLEAN -- Convenience feature do Result := step.player = {NATIONALITY_CONSTANTS}.Japanese end is_allied_player: BOOLEAN -- Convenience feature do Result := step.player = {NATIONALITY_CONSTANTS}.Allied end is_step_executable: BOOLEAN -- Does the current step have a command that can be -- automatically executed? do Result := step.is_executable end is_step_completed: BOOLEAN -- Is the current step in a state that allow the player -- to advance to the next step? do Result := step.is_completed end is_reinforcement_step: BOOLEAN -- Is the current step on placing reinforcements? do Result := attached {JAPANESE_REINFORCEMENT_STEP} step or attached {ALLIED_REINFORCEMENT_STEP} step end is_patrolling_step: BOOLEAN -- Is the game at the patrolling step do Result := attached {JAPANESE_MOVE_PATROLLERS_STEP} step or attached {ALLIED_MOVE_PATROLLERS_STEP} step end is_raiding_step: BOOLEAN -- Is the game at the raiding step do io.put_string (generating_type.name + ".is_raiding_step: fix me %N") end is_moving_amphibious_step: BOOLEAN -- Is the game at a place where amphibious units can move? do io.put_string (generating_type.name + ".is_moving_amphibious_step: fix me! %N") end is_moving_submarine_step: BOOLEAN -- Is the game at a step where the submarine can move? do io.put_string (generating_type.name + ".is_moving_submarine_step: fix me! %N") end feature -- Basic operations execute_step_actions -- Perform the actions associated with the current step require is_step_executable: is_step_executable do step.execute end feature -- Status report is_before: BOOLEAN -- Is the cursor before Current? do Result := path.is_empty end is_after: BOOLEAN -- Is the cursor after Current? do Result := step = turns.last and then step.index > step.count end is_off: BOOLEAN -- Is the cursor before of after? do Result := is_before or is_after end feature -- Basic operations show_path -- Display the current path for testing do from path.start until path.exhausted loop print (path.item.node.name + ":" + path.item.index.out) if not path.after then print (", ") end path.forth end print ("%N") end start -- Move to the first sub-`step' or `is_after' local tab: VITP_TABLE [ATTACK_UNIT] u: ATTACK_UNIT do from turns.start until turns.after loop turns.item.start turns.forth end turns.start path.wipe_out path.extend (turns.first, 1) if can_go_down then go_down end -- Put the game in correct starting state tab := game.all_attack_units from tab.start until tab.after loop u := tab.item_for_iteration if u.nationality = {NATIONALITY_CONSTANTS}.Japanese then u.set_location (game.Japanese_oa_chart) else if u.arrival_turn = 1 then u.set_location (game.Allied_starting_forces_chart) else u.set_location (game.Allied_oa_chart) end end tab.forth end end forth -- Move to the next step require not_after: not is_after local i: INTEGER n: like step do i := index + 1 n := step n.forth if n.is_after then if can_go_up then go_up end elseif can_go_down then go_down elseif can_go_right then go_right else check is_after: is_after -- Because no other direction to go end end end feature {NONE} -- Implementation turns: ARRAYED_LIST [VITP_TURN] -- The turns in Current path: ARRAYED_LIST [TUPLE [node: like step; index: like index]] -- The node-and-index TUPLES through which this `iterator' has taken -- to reach a leaf. step: GAME_STEP -- The node at the end of the current `path' do Result := path.last.node end index: INTEGER -- The index into the array in `node' to get the next node -- (i.e. the index of the edge out of `node') do Result := path.last.index end go_up -- require not_after: not is_after can_go_up: can_go_up local n: like step i: INTEGER do path.remove_i_th (path.count) path.go_i_th (path.count) -- path.replace ([step, index + 1]) -- Next line keeps the `step's internal `index' correct step.forth path.replace ([step, step.index]) if can_go_down then go_down else go_up end end go_down -- require not_after: not is_after can_go_down: can_go_down local n: like step do -- Keep going down to leaf from until step.is_empty loop n := step.i_th (index) path.extend ([n, 1]) if can_go_down then go_down end end end go_right -- require not_after: not is_after can_go_right: can_go_right do print ("go_right ") end can_go_up: BOOLEAN -- Is there a parent node to move up to? do Result := step.has_parent end can_go_down: BOOLEAN -- Is there a child node at the `index' of current `node' local s: GAME_STEP do -- Result := index <= step.count -- s := path.last.node -- Result := not (s.is_off or s.item.is_completed) Result := not step.is_off end can_go_right: BOOLEAN -- Is there a sibling branch to the right of this index? end