package chess.model; import java.util.Stack; import chess.controller.PlayerCommand; import chess.controller.commands.MoveCommand; import chess.model.visitor.PawnIdentifier; public class Game { private final ChessBoard board; private Color playerTurn; private final Stack movesHistory; public enum GameStatus { Check, CheckMate, OnGoing, Pat; } public Game(ChessBoard board) { this.board = board; this.movesHistory = new Stack<>(); } public ChessBoard getBoard() { return board; } public Color getPlayerTurn() { return playerTurn; } public void resetPlayerTurn() { this.playerTurn = Color.White; } public void switchPlayerTurn() { playerTurn = Color.getEnemy(playerTurn); } public GameStatus checkGameStatus() { final Color enemy = Color.getEnemy(getPlayerTurn()); if (this.board.isKingInCheck(enemy)) if (this.board.hasAllowedMoves(enemy)) return GameStatus.Check; else return GameStatus.CheckMate; if (!board.hasAllowedMoves(enemy)) return GameStatus.Pat; return GameStatus.OnGoing; } public boolean pawnShouldBePromoted() { return pawnPromotePosition() != null; } /** * * @return Null if there is no pawn to promote */ public Coordinate pawnPromotePosition() { Coordinate piecePos = pawnPromotePosition(Color.White); if (piecePos != null) return piecePos; return pawnPromotePosition(Color.Black); } /** * * @return Null if there is no pawn to promote */ private Coordinate pawnPromotePosition(Color color) { int enemyLineY = color == Color.White ? 0 : 7; PawnIdentifier identifier = new PawnIdentifier(color); for (int x = 0; x < Coordinate.VALUE_MAX; x++) { Coordinate pieceCoords = new Coordinate(x, enemyLineY); Piece piece = getBoard().pieceAt(pieceCoords); if (identifier.isPawn(piece)) return pieceCoords; } return null; } public void addAction(PlayerCommand command) { this.movesHistory.add(command); } public PlayerCommand getLastAction() { if (this.movesHistory.isEmpty()) return null; return this.movesHistory.pop(); } public void updateLastMove() { if (this.movesHistory.isEmpty()) return; PlayerCommand last = this.movesHistory.getLast(); if (last instanceof MoveCommand move) { this.board.setLastMove(move.getMove()); } } }