package uulm.teamname.marvelous.gamelibrary.gamelogic; import uulm.teamname.marvelous.gamelibrary.events.Event; import uulm.teamname.marvelous.gamelibrary.events.EventType; import uulm.teamname.marvelous.gamelibrary.requests.Request; import java.util.ArrayList; import java.util.List; /** Represents manager for a game state. */ class GameStateManager { /** The managed {@link GameState} */ private final GameState state; /** The queue of {@link Event Events} to be applied during {@link Request} processing */ private final ArrayList queue = new ArrayList<>(); /** * Constructs a new {@link GameStateManager}. * @param state A reference to the state to be managed */ public GameStateManager(GameState state) { this.state = state; } /** * Checks a list of {@link Request Requests} for validity and optionally produces resulting {@link Event Events}. * @param requests The requests to check * @param apply True if resulting events should be stored for later application * @return Whether the requests are valid */ public boolean processRequests(ArrayList requests, boolean apply) { GameState snapshot = state.snapshot(); for(Request request: requests) { if (GameLogic.checkRequest(snapshot, request)) { ArrayList result = GameLogic.executeRequest(snapshot, request); for(Event event: result) { GameLogic.applyEvent(snapshot, event); } if(apply) { queue.addAll(result); } }else { queue.clear(); return false; } } return true; } /** * Applies an array of {@link Event Events} to the game state. * @param events The events to apply */ public void applyEvents(Event[] events) { for(Event event: events) { GameLogic.applyEvent(state, event); } } /** * Applies an array of {@link Event Events} to the game state. * @param events The events to apply */ public void applyEvents(List events) { for(Event event: events) { GameLogic.applyEvent(state, event); } } /** * Applies an {@link Event} to the game state. * @param event The event to apply */ public void applyEvent(Event event) { GameLogic.applyEvent(state, event); } /** * Applies the result of the last processRequests call. * @return A list of applied events */ public ArrayList apply() { for(Event event: queue) { GameLogic.applyEvent(state, event); } // i feel so smart for remembering this trick try { return new ArrayList<>(queue); }finally { queue.clear(); } } /** * Handles events that happen after a turn phase. * @return The optionally resulting {@link Event Events} */ public ArrayList checkPostPhase() { GameState snapshot = state.snapshot(); ArrayList result = GameLogic.checkTurnEnd(snapshot); applyEvents(result); return result; } /** * Initializes and starts the game. * @param selectedCharacters1 The characters selected by player 1 * @param selectedCharacters2 The characters selected by player 2 * @return The resulting {@link Event Events} */ public List startGame(List selectedCharacters1, List selectedCharacters2) { GameState snapshot = state.snapshot(); ArrayList result = GameLogic.startGame(snapshot, selectedCharacters1, selectedCharacters2); applyEvents(result); snapshot = state.snapshot(); ArrayList result2 = GameLogic.startRound(snapshot); applyEvents(result2); result.addAll(result2); return result; } /** * Forcefully ends the current turn. * @return The resulting {@link Event Events} */ public ArrayList endTurn() { GameState snapshot = state.snapshot(); ArrayList result = GameLogic.endTurn(snapshot); applyEvents(result); return result; } /** * Produces a {@link EventType#GamestateEvent} for the current {@link GameState}. * @return The resulting event */ public Event getGameStateEvent() { return GameLogic.buildGameStateEvent(state); } }