package uulm.teamname.marvelous.gamelibrary.gamelogic; import uulm.teamname.marvelous.gamelibrary.IntVector2; import uulm.teamname.marvelous.gamelibrary.entities.Entity; import uulm.teamname.marvelous.gamelibrary.events.Event; import uulm.teamname.marvelous.gamelibrary.events.EventType; import uulm.teamname.marvelous.gamelibrary.config.CharacterConfig; import uulm.teamname.marvelous.gamelibrary.config.PartyConfig; import uulm.teamname.marvelous.gamelibrary.config.ScenarioConfig; import uulm.teamname.marvelous.gamelibrary.requests.Request; import java.util.ArrayList; import java.util.List; import java.util.Optional; /** Represents a game instance. */ public class GameInstance { /** The private {@link GameState} of the instance */ private final GameState _state; /** The public view for the underlying {@link GameState} of the instance */ public final GameStateView state; /** The {@link GameStateManager} managing the {@link GameState} of the instance */ private final GameStateManager manager; /** Constructs a new {@link GameInstance}. */ public GameInstance(PartyConfig partyConfig, CharacterConfig characterConfig, ScenarioConfig scenarioConfig) { _state = new GameState(partyConfig, characterConfig, scenarioConfig); state = new GameStateView(_state); manager = new GameStateManager(_state); } /** * Checks an array of {@link Request}s for validity and automatically applies them if valid. * @param requests The requests to check * @return The list of resulting {@link Event}s or `null` if the check failed */ public Optional> checkRequestsAndApply(ArrayList requests) { if(manager.processRequests(requests, true)) { ArrayList result = manager.apply(); result.addAll(manager.checkPostPhase()); return Optional.of(result); } return Optional.empty(); } /** * Checks an array of {@link Request}s for validity without applying it. * @param requests The requests to check * @return Whether or not the given set of requests is valid */ public boolean checkRequests(ArrayList requests) { return manager.processRequests(requests, false); } /** * Applies an array of {@link Event}s to the game state. * @param events The events to apply. */ public void applyEvents(ArrayList events) { manager.applyEvents(events); } /** * Initializes and starts the game. Selected characters are given as a list of indices from the {@link CharacterConfig#characters} array. * @param selectedCharacters1 The characters selected by player 1 * @param selectedCharacters2 The characters selected by player 2 * @return The list of resulting {@link Event}s */ public ArrayList startGame(ArrayList selectedCharacters1, ArrayList selectedCharacters2) { return manager.startGame(selectedCharacters1, selectedCharacters2); } /** * Forcefully ends the current turn. * @return The list of resulting {@link Event}s */ public ArrayList endTurn() { return manager.endTurn(); } /** * Produces a {@link EventType#GamestateEvent} for the current {@link GameState}. * @return The resulting event */ public Event getGameStateEvent() { return manager.getGameStateEvent(); } /** * Restores the current {@link GameState} based on the given {@link EventType#GamestateEvent}. * @param gameStateEvent The event to restore from */ public void applyGameStateEvent(Event gameStateEvent) { manager.applyEvent(gameStateEvent); } @Override public String toString() { StringBuilder sb = new StringBuilder(); for(int y = 0; y < _state.mapSize.getY(); y++) { for(int x = 0; x < _state.mapSize.getX(); x++) { ArrayList entities = _state.entities.findByPosition(new IntVector2(x, y)); if(entities.isEmpty()) { sb.append(". "); }else { switch(entities.get(0).id.type) { case NPC -> { switch(entities.get(0).id.id) { case 0 -> { sb.append("G "); } case 1 -> { sb.append("S "); } case 2 -> { sb.append("T "); } } } case P1, P2 -> { sb.append("X "); } case Rocks -> { sb.append("O "); } case InfinityStones -> { sb.append("# "); } } } } sb.append("\n"); } return sb.toString(); } }