mourning-ember / src / main / java / dev / llan / model / Game.java
Game.java
Raw
package dev.llan.model;

import dev.llan.events.Events.*;
import dev.llan.events.SwitchStateEvent;
import dev.llan.model.board.GameMap;
import dev.llan.model.board.Point;
import dev.llan.events.GameEvent;
import dev.llan.model.pieces.Entity;
import dev.llan.model.pieces.GamePieces;
import dev.llan.model.pieces.inanimates.Inanimate;
import dev.llan.model.pieces.enemies.Enemy;
import dev.llan.model.pieces.player.Player;
import dev.llan.model.state.*;
import dev.llan.model.state.combat.CombatManager.CombatPhase;
import dev.llan.model.state.combat.TurnInfo;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

import static dev.llan.model.Constants.*;

public class Game {
  private GameMap map;
  private Player player;
  private List<Enemy> enemies;
  private List<Inanimate> inanimates;

  private GameState state;
  private int floor;
  private int score;

  public Game(int size) {
    score = 0;
    floor = 1;
    map = new GameMap(this, size);
    this.initGamePieces();
    this.state = new Exploration(this);
    map.updateGameState(State.EXPLORATION);
  }

  public void nextFloor() {
    floor++;
    score += floor * FLOOR_BONUS;
    if (floor <= MAX_FLOOR) {
      this.generateNextFloor();
    } else {
      this.win();
    }
  }

  private void initGamePieces() {
    GamePieces initialized = map.init();
    player = initialized.player();
    enemies = initialized.enemies();
    inanimates = initialized.inanimates();
  }

  private void generateNextFloor() {
    GamePieces nextInitialized = map.initNext(player);
    enemies = nextInitialized.enemies();
    inanimates = nextInitialized.inanimates();
  }

  public void addScore(int score) {
    this.score += score;
  }

  public List<GameEvent> setState(State newState) {
    List<GameEvent> events = new ArrayList<>();
    switch (newState) {
      case COMBAT -> state = new Combat(this);
      case EXPLORATION -> state = new Exploration(this);
      default -> throw new IllegalArgumentException("Input is not a valid game state");
    }
    map.updateGameState(newState);
    events.addAll(state.onSwapTo());
    events.add(new SwitchStateEvent(newState));
    return events;
  }

  public State getState() {
    return this.state.getState();
  }

  public CombatPhase getPhase() {
    if (state instanceof Combat) {
      return ((Combat) state).getPhase();
    }
    return CombatPhase.NONE;
  }

  public Optional<Entity> getTurn() {
    if (state.getState() == State.COMBAT) {
      Entity entity = ((Combat) state).getCurrentTurn();
      if(entity != null) {
        return Optional.of(entity);
      }
    }
    return Optional.empty();
  }

  public List<TurnInfo> getTurnsList() {
    if(state.getState() == State.COMBAT) {
      return ((Combat) state).getTurnsList();
    }
    return List.of();
  }

  public List<GameEvent> tryMoveTo(Point position) {
    return state.tryMoveTo(position);
  }

  public List<GameEvent> moveActivePath() {
    return state.moveActivePath();
  }

  public List<GameEvent> endTurn() {
    return state.endTurn();
  }

  public List<GameEvent> waitTurn() {
    return state.waitTurn();
  }

  public List<GameEvent> useCardOn(Point position) {
    return state.useCardOn(position);
  }

  public List<GameEvent> swapCards(int first, int second) {
    return state.swapCards(first, second);
  }

  public List<GameEvent> selectCard(int cardIndex) {
    return state.selectCard(cardIndex);
  }

  public List<GameEvent> removeCard(int index) {
    return state.removeCard(index);
  }

  public List<GameEvent> equip(int index) {
    return state.equip(index);
  }

  public List<GameEvent> swapEquipment(int first, int second) {
    return state.swapEquipment(first, second);
  }

  public List<GameEvent> removeEquipment(int index) {
    return state.removeEquipment(index);
  }

  public List<GameEvent> setHighlighted(Point point, boolean highlighted) {
    return state.setHighlighted(point, highlighted);
  }

  public GameMap getMap() {
    return map;
  }

  public Player getPlayer() {
    return player;
  }

  public List<Enemy> getEnemies() {
    return enemies;
  }

  public List<Inanimate> getInanimates() {
    return inanimates;
  }

  public int getFloor() {
    return floor;
  }

  public int getScore() {
    return score;
  }

  public void removeEnemy(Enemy enemy) {
    enemies.remove(enemy);
  }

  public void removeInanimate(Inanimate inanimate) {
    inanimates.remove(inanimate);
  }

  public void end() {
    state = new End(this);
  }

  public void win() {
    state = new Win(this);
  }

  public GameRecord getImmutableSnapshot(EventType eventType) {
    return new GameRecord(this, eventType);
  }
}