159 lines
3.2 KiB
Java
159 lines
3.2 KiB
Java
package chess.model;
|
|
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Stack;
|
|
|
|
import chess.controller.PlayerCommand;
|
|
import chess.controller.commands.MoveCommand;
|
|
|
|
/**
|
|
* Game class that represents a chess game.
|
|
*/
|
|
|
|
public class Game {
|
|
private final ChessBoard board;
|
|
private Color playerTurn;
|
|
private final Stack<PlayerCommand> movesHistory;
|
|
private final Map<Integer, Integer> traitsPos;
|
|
|
|
private static final int DRAW_REPETITONS = 3;
|
|
|
|
public enum GameStatus {
|
|
Draw, Check, CheckMate, OnGoing, Pat;
|
|
}
|
|
|
|
public Game() {
|
|
this.board = new ChessBoard();
|
|
this.movesHistory = new Stack<>();
|
|
this.traitsPos = new HashMap<>();
|
|
}
|
|
|
|
public ChessBoard getBoard() {
|
|
return board;
|
|
}
|
|
|
|
public Color getPlayerTurn() {
|
|
return playerTurn;
|
|
}
|
|
|
|
/**
|
|
* Reset the game
|
|
*/
|
|
public void reset() {
|
|
resetPlayerTurn();
|
|
this.traitsPos.clear();
|
|
}
|
|
|
|
/**
|
|
* Reset the player turn.
|
|
* Aka: white for the win
|
|
*/
|
|
public void resetPlayerTurn() {
|
|
this.playerTurn = Color.White;
|
|
}
|
|
|
|
/**
|
|
* Save the current board configuration
|
|
*/
|
|
public void saveTraitPiecesPos() {
|
|
int piecesHash = this.board.hashCode();
|
|
Integer count = this.traitsPos.get(piecesHash);
|
|
this.traitsPos.put(piecesHash, count == null ? 1 : count + 1);
|
|
}
|
|
|
|
|
|
/**
|
|
* @return whether the game is in a draw situation
|
|
*/
|
|
private boolean checkDraw() {
|
|
return this.traitsPos.containsValue(DRAW_REPETITONS);
|
|
}
|
|
|
|
/**
|
|
* Switch player turn
|
|
*/
|
|
public void switchPlayerTurn() {
|
|
playerTurn = Color.getEnemy(playerTurn);
|
|
}
|
|
|
|
/**
|
|
* Check the status of the game ofr the specified player
|
|
* @return a GameStatus enum
|
|
*/
|
|
public GameStatus checkGameStatus(Color color) {
|
|
if (checkDraw())
|
|
return GameStatus.Draw;
|
|
|
|
if (this.board.isKingInCheck(color))
|
|
if (this.board.hasAllowedMoves(color))
|
|
return GameStatus.Check;
|
|
else
|
|
return GameStatus.CheckMate;
|
|
|
|
if (!board.hasAllowedMoves(color))
|
|
return GameStatus.Pat;
|
|
|
|
return GameStatus.OnGoing;
|
|
}
|
|
|
|
/**
|
|
* Check the status of the gamere
|
|
*/
|
|
public GameStatus checkGameStatus() {
|
|
return checkGameStatus(Color.getEnemy(getPlayerTurn()));
|
|
}
|
|
|
|
/**
|
|
* Add a player move (basic move, castling, ...) to the game history.
|
|
*/
|
|
public void addAction(PlayerCommand command) {
|
|
this.movesHistory.add(command);
|
|
}
|
|
|
|
/**
|
|
* @return the last player action
|
|
*/
|
|
public PlayerCommand getLastAction() {
|
|
if (this.movesHistory.isEmpty())
|
|
return null;
|
|
return this.movesHistory.pop();
|
|
}
|
|
|
|
/**
|
|
* Update the last board move ater an undo.
|
|
*/
|
|
public void updateLastMove() {
|
|
if (this.movesHistory.isEmpty())
|
|
return;
|
|
|
|
PlayerCommand last = this.movesHistory.getLast();
|
|
if (last instanceof MoveCommand move) {
|
|
this.board.setLastMove(move.getMove());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Remove the board configuration occurence from the game history
|
|
*/
|
|
public void undoTraitPiecesPos() {
|
|
int piecesHash = this.board.hashCode();
|
|
Integer count = this.traitsPos.get(piecesHash);
|
|
if (count != null)
|
|
this.traitsPos.put(piecesHash, count - 1);
|
|
}
|
|
|
|
public List<PlayerCommand> getMoves() {
|
|
return this.movesHistory;
|
|
}
|
|
|
|
/**
|
|
* @return wether a pawn should be promoted
|
|
*/
|
|
public boolean pawnShouldBePromoted() {
|
|
return this.board.pawnShouldBePromoted();
|
|
}
|
|
|
|
}
|