doc, fin
All checks were successful
Linux arm64 / Build (push) Successful in 34s

This commit is contained in:
2025-05-18 23:30:30 +02:00
parent 97950403a5
commit c741044469
18 changed files with 465 additions and 45 deletions

View File

@@ -54,6 +54,10 @@ public class ChessBoard {
this.kingPos = new Coordinate[Color.values().length];
}
/**
* Apply a move on the board.
* @param move move to apply
*/
public void applyMove(Move move) {
assert move.isValid() : "Invalid move !";
Piece deadPiece = pieceAt(move.getDeadPieceCoords());
@@ -70,12 +74,20 @@ public class ChessBoard {
this.lastVirtualMove = move;
}
/**
* Undo the last move
*/
public void undoLastMove() {
assert this.lastVirtualMove != null : "Can't undo at the beginning!";
undoMove(this.lastVirtualMove, this.lastEjectedPiece);
}
/**
* Undo the specified move
* @param move
* @param deadPiece
*/
public void undoMove(Move move, Piece deadPiece) {
Piece movingPiece = pieceAt(move.getFinish());
pieceComes(movingPiece, move.getStart());
@@ -85,16 +97,29 @@ public class ChessBoard {
movingPiece.unMove();
}
/**
* Check if the cell is empty
* @param coordinate
* @return true if the cell is empty
*/
public boolean isCellEmpty(Coordinate coordinate) {
return pieceAt(coordinate) == null;
}
/**
* Return the piece at the given coordinates
* @param coordinate
* @return piece at the given coordinates, or null if the coordinates are invalid or the cell is empty
*/
public Piece pieceAt(Coordinate coordinate) {
if (!coordinate.isValid())
return null;
return cellAt(coordinate).getPiece();
}
/**
* Nuke all pieces of the board
*/
public void clearBoard() {
for (int i = 0; i < Coordinate.VALUE_MAX; i++) {
for (int j = 0; j < Coordinate.VALUE_MAX; j++) {
@@ -103,24 +128,48 @@ public class ChessBoard {
}
}
/**
* Get the cell at the given coordinates
* @param coordinate
* @return
*/
private Cell cellAt(Coordinate coordinate) {
return this.cells[coordinate.getX()][coordinate.getY()];
}
/*
* Set the piece at the given coordinate
*/
public void pieceComes(Piece piece, Coordinate coordinate) {
cellAt(coordinate).setPiece(piece);
if (piece instanceof King)
this.kingPos[piece.getColor().ordinal()] = coordinate;
}
/**
* Remove the piece at the given coordiinates
* @param coordinate
*/
public void pieceLeaves(Coordinate coordinate) {
cellAt(coordinate).setPiece(null);
}
/**
* Find the king of the given color on the board
* @param color
* @return the coordinates of the king
*/
public Coordinate findKing(Color color) {
return kingPos[color.ordinal()];
}
/**
* Get the allowed starting positions for a piece to attack the given Coordinate. Useful for PGN trasnlation.
* @param finish
* @param color
* @return coordinates of the pieces that could attack
*/
public List<Coordinate> getAllowedStarts(Coordinate finish, Color color) {
List<Coordinate> starts = new ArrayList<>();
for (int i = 0; i < Coordinate.VALUE_MAX; i++) {
@@ -145,6 +194,11 @@ public class ChessBoard {
return starts;
}
/**
* Check if the king of the given color is in check
* @param color
* @return true if the king is in check
*/
public boolean isKingInCheck(Color color) {
Coordinate kingPos = findKing(color);
assert kingPos.isValid() : "King position is invalid!";
@@ -164,10 +218,20 @@ public class ChessBoard {
return false;
}
/**
* Check if the given player has allowed moves
* @param player
* @return true if the player can move
*/
public boolean hasAllowedMoves(Color player) {
return !getAllowedMoves(player).isEmpty();
}
/**
* Get the allowed moves for the given player
* @param player
* @return
*/
public List<Move> getAllowedMoves(Color player) {
if (this.cachedAllowedMoves != null) {
return this.cachedAllowedMoves;
@@ -211,7 +275,10 @@ public class ChessBoard {
return result;
}
public List<Coordinate> getAllowedMoves(Coordinate pieceCoords) {
/**
* Get all the end positions possible of a piece
*/
public List<Coordinate> getPieceAllowedMoves(Coordinate pieceCoords) {
Piece piece = pieceAt(pieceCoords);
if (piece == null)
return null;
@@ -239,6 +306,13 @@ public class ChessBoard {
return result;
}
/**
* Check if the given player can castle with the given rook
* @param color
* @param rookX
* @param kingDirection
* @return true if the player can Castle
*/
private boolean canCastle(Color color, int rookX, Direction kingDirection) {
if (isKingInCheck(color))
return false;
@@ -273,20 +347,32 @@ public class ChessBoard {
return obstacle == null;
}
/**
* @return wether the player can perform a kingside castling.
*/
public boolean canSmallCastle(Color color) {
return canCastle(color, 7, Direction.Right);
}
/**
* Check if the given player is allowed to execute a queenside castling.
* @param color
* @return
*/
public boolean canBigCastle(Color color) {
return canCastle(color, 0, Direction.Left);
}
/**
* Check if there is a pawn to be promoted by the given player.
* @return
*/
public boolean pawnShouldBePromoted() {
return pawnPromotePosition() != null;
}
/**
*
* Check if there's a pawn in the adversary line on the board
* @return Null if there is no pawn to promote
*/
public Coordinate pawnPromotePosition() {
@@ -297,7 +383,7 @@ public class ChessBoard {
}
/**
*
* Check if there's a pawn of the given player in the adversary line on the board
* @return Null if there is no pawn to promote
*/
private Coordinate pawnPromotePosition(Color color) {
@@ -315,6 +401,10 @@ public class ChessBoard {
return null;
}
/**
* Hash according to the pieces position on the board
* @return hash code
*/
@Override
public int hashCode() {
int result = 0;
@@ -329,10 +419,16 @@ public class ChessBoard {
return result;
}
/**
* @return the last played move
*/
public Move getLastMove() {
return this.lastMove;
}
/**
* Updates the last move of the board and invalidate the allowedMoves cache.
*/
public void setLastMove(Move lastMove) {
this.lastMove = lastMove;
this.cachedAllowedMoves = null;

View File

@@ -38,19 +38,24 @@ public class Game {
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;
}
/**
*
* @param color the current player turn
* @return true if a draw should be declared
* Save the current board configuration
*/
public void saveTraitPiecesPos() {
int piecesHash = this.board.hashCode();
@@ -67,14 +72,16 @@ public class Game {
}
/**
*
* @return true if a draw should occur
* Switch player turn
*/
public void switchPlayerTurn() {
playerTurn = Color.getEnemy(playerTurn);
}
// this is the bottleneck of algorithms using this chess engine
/**
* Check the status of the game ofr the specified player
* @return a GameStatus enum
*/
public GameStatus checkGameStatus(Color color) {
if (checkDraw())
return GameStatus.Draw;
@@ -91,20 +98,32 @@ public class Game {
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;
@@ -115,6 +134,9 @@ public class Game {
}
}
/**
* Remove the board configuration occurence from the game history
*/
public void undoTraitPiecesPos() {
int piecesHash = this.board.hashCode();
Integer count = this.traitsPos.get(piecesHash);
@@ -126,6 +148,9 @@ public class Game {
return this.movesHistory;
}
/**
* @return wether a pawn should be promoted
*/
public boolean pawnShouldBePromoted() {
return this.board.pawnShouldBePromoted();
}

View File

@@ -15,6 +15,10 @@ public class Move {
this.deadPieceCoords = finish;
}
/**
*
* @return true if the move is valid, false otherwise
*/
public boolean isValid() {
return this.start.isValid() && this.finish.isValid() && !this.start.equals(this.finish);
}
@@ -27,6 +31,10 @@ public class Move {
return finish;
}
/**
* Returns the number of cells traversed by the move.
* @return int
*/
public int traversedCells() {
assert isValid() : "Move is invalid!";
@@ -45,6 +53,9 @@ public class Move {
return 0;
}
/**
* @return the coordinates of the cell in the middle of the move
*/
public Coordinate getMiddle() {
return Coordinate.fromIndex((getStart().toIndex() + getFinish().toIndex()) / 2);
}