|
|
|
@ -13,45 +13,15 @@ import dev.kske.chess.board.Piece.Color;
|
|
|
|
|
*/
|
|
|
|
|
public class Log implements Cloneable {
|
|
|
|
|
|
|
|
|
|
private List<LoggedMove> moves;
|
|
|
|
|
private Color activeColor;
|
|
|
|
|
private List<LoggedMove> moves;
|
|
|
|
|
|
|
|
|
|
private Position enPassant;
|
|
|
|
|
private Color activeColor;
|
|
|
|
|
private int fullmoveCounter, halfmoveClock;
|
|
|
|
|
|
|
|
|
|
public Log() {
|
|
|
|
|
moves = new ArrayList<>();
|
|
|
|
|
activeColor = Color.WHITE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void add(Move move, Piece capturedPiece, boolean pawnMove) {
|
|
|
|
|
// En passant availability
|
|
|
|
|
Position enPassant = null;
|
|
|
|
|
if (pawnMove && move.yDist == 2) enPassant = new Position(move.pos.x, move.pos.y + move.ySign);
|
|
|
|
|
|
|
|
|
|
// Fullmove counter and halfmove clock
|
|
|
|
|
int fullmoveCounter, halfmoveClock;
|
|
|
|
|
if (moves.isEmpty()) {
|
|
|
|
|
fullmoveCounter = 1;
|
|
|
|
|
halfmoveClock = 0;
|
|
|
|
|
} else {
|
|
|
|
|
fullmoveCounter = getLast().fullmoveCounter;
|
|
|
|
|
if (activeColor == Color.BLACK) ++fullmoveCounter;
|
|
|
|
|
halfmoveClock = capturedPiece != null || pawnMove ? 0 : getLast().halfmoveClock + 1;
|
|
|
|
|
}
|
|
|
|
|
activeColor = activeColor.opposite();
|
|
|
|
|
moves.add(new LoggedMove(move, capturedPiece, enPassant, fullmoveCounter, halfmoveClock));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public LoggedMove getLast() { return moves.isEmpty() ? null : moves.get(moves.size() - 1); }
|
|
|
|
|
|
|
|
|
|
public void removeLast() {
|
|
|
|
|
if (!moves.isEmpty()) {
|
|
|
|
|
activeColor = activeColor.opposite();
|
|
|
|
|
moves.remove(moves.size() - 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void reset() {
|
|
|
|
|
moves.clear();
|
|
|
|
|
activeColor = Color.WHITE;
|
|
|
|
|
moves = new ArrayList<>();
|
|
|
|
|
reset();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
@ -67,23 +37,103 @@ public class Log implements Cloneable {
|
|
|
|
|
return log;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Adds a move to the move history and adjusts the log to the new position.
|
|
|
|
|
*
|
|
|
|
|
* @param move The move to log
|
|
|
|
|
* @param capturedPiece The piece captured with the move
|
|
|
|
|
* @param pawnMove {@code true} if the move was made by a pawn
|
|
|
|
|
*/
|
|
|
|
|
public void add(Move move, Piece capturedPiece, boolean pawnMove) {
|
|
|
|
|
// En passant availability
|
|
|
|
|
enPassant = pawnMove && move.yDist == 2 ? new Position(move.pos.x, move.pos.y + move.ySign) : null;
|
|
|
|
|
|
|
|
|
|
// Fullmove counter and halfmove clock
|
|
|
|
|
int fullmoveCounter, halfmoveClock;
|
|
|
|
|
if (moves.isEmpty()) {
|
|
|
|
|
fullmoveCounter = 1;
|
|
|
|
|
halfmoveClock = 0;
|
|
|
|
|
} else {
|
|
|
|
|
fullmoveCounter = getLast().fullmoveCounter;
|
|
|
|
|
if (activeColor == Color.BLACK) ++fullmoveCounter;
|
|
|
|
|
halfmoveClock = capturedPiece != null || pawnMove ? 0 : getLast().halfmoveClock + 1;
|
|
|
|
|
}
|
|
|
|
|
activeColor = activeColor.opposite();
|
|
|
|
|
moves.add(new LoggedMove(move, capturedPiece, enPassant, activeColor, fullmoveCounter, halfmoveClock));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return the last logged move, or {@code null} if there is none
|
|
|
|
|
*/
|
|
|
|
|
public LoggedMove getLast() { return moves.isEmpty() ? null : moves.get(moves.size() - 1); }
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Removed the last move from the log and adjusts its state to the previous
|
|
|
|
|
* move.
|
|
|
|
|
*/
|
|
|
|
|
public void removeLast() {
|
|
|
|
|
if (!isEmpty()) {
|
|
|
|
|
moves.remove(moves.size() - 1);
|
|
|
|
|
if (!isEmpty()) {
|
|
|
|
|
LoggedMove last = moves.get(moves.size() - 1);
|
|
|
|
|
activeColor = last.activeColor;
|
|
|
|
|
enPassant = last.enPassant;
|
|
|
|
|
fullmoveCounter = last.fullmoveCounter;
|
|
|
|
|
halfmoveClock = last.halfmoveClock;
|
|
|
|
|
} else reset();
|
|
|
|
|
} else reset();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public boolean isEmpty() { return moves.isEmpty(); }
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Reverts the log to its initial state corresponding to the default board
|
|
|
|
|
* position.
|
|
|
|
|
*/
|
|
|
|
|
public void reset() {
|
|
|
|
|
moves.clear();
|
|
|
|
|
enPassant = null;
|
|
|
|
|
activeColor = Color.WHITE;
|
|
|
|
|
fullmoveCounter = 1;
|
|
|
|
|
halfmoveClock = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public List<LoggedMove> getLoggedMoves() { return moves; }
|
|
|
|
|
|
|
|
|
|
public List<LoggedMove> getMoves() { return moves; }
|
|
|
|
|
|
|
|
|
|
public void setMoves(List<LoggedMove> moves) { this.moves = moves; }
|
|
|
|
|
|
|
|
|
|
public Position getEnPassant() { return enPassant; }
|
|
|
|
|
|
|
|
|
|
public void setEnPassant(Position enPassant) { this.enPassant = enPassant; }
|
|
|
|
|
|
|
|
|
|
public Color getActiveColor() { return activeColor; }
|
|
|
|
|
|
|
|
|
|
public void setActiveColor(Color activeColor) { this.activeColor = activeColor; }
|
|
|
|
|
|
|
|
|
|
public List<LoggedMove> getLoggedMoves() { return moves; }
|
|
|
|
|
public int getFullmoveCounter() { return fullmoveCounter; }
|
|
|
|
|
|
|
|
|
|
public void setFullmoveCounter(int fullmoveCounter) { this.fullmoveCounter = fullmoveCounter; }
|
|
|
|
|
|
|
|
|
|
public int getHalfmoveClock() { return halfmoveClock; }
|
|
|
|
|
|
|
|
|
|
public void setHalfmoveClock(int halfmoveClock) { this.halfmoveClock = halfmoveClock; }
|
|
|
|
|
|
|
|
|
|
public static class LoggedMove {
|
|
|
|
|
|
|
|
|
|
public final Move move;
|
|
|
|
|
public final Piece capturedPiece;
|
|
|
|
|
public final Position enPassant;
|
|
|
|
|
public final Color activeColor;
|
|
|
|
|
public final int fullmoveCounter, halfmoveClock;
|
|
|
|
|
|
|
|
|
|
public LoggedMove(Move move, Piece capturedPiece, Position enPassant, int fullmoveCounter, int halfmoveClock) {
|
|
|
|
|
public LoggedMove(Move move, Piece capturedPiece, Position enPassant, Color activeColor, int fullmoveCounter,
|
|
|
|
|
int halfmoveClock) {
|
|
|
|
|
this.move = move;
|
|
|
|
|
this.capturedPiece = capturedPiece;
|
|
|
|
|
this.enPassant = enPassant;
|
|
|
|
|
this.activeColor = activeColor;
|
|
|
|
|
this.fullmoveCounter = fullmoveCounter;
|
|
|
|
|
this.halfmoveClock = halfmoveClock;
|
|
|
|
|
}
|
|
|
|
|