Cleaned up and improved Log

+ Current log state properties
- Removed Log delegates from Board
This commit is contained in:
Kai S. K. Engelbart 2019-08-12 06:44:55 +02:00
parent 14c7167ce4
commit d121e85897
5 changed files with 95 additions and 55 deletions

View File

@ -571,14 +571,4 @@ public class Board implements Cloneable {
* @return The move log * @return The move log
*/ */
public Log getLog() { return log; } public Log getLog() { return log; }
/**
* @return The active color for the next move
*/
public Color getActiveColor() { return log.getActiveColor(); }
/**
* @return The current en passant square, or null if there isn't any
*/
public Position getEnPassantSquare() { return log.getLast() == null ? null : log.getLast().enPassant; }
} }

View File

@ -14,44 +14,14 @@ import dev.kske.chess.board.Piece.Color;
public class Log implements Cloneable { public class Log implements Cloneable {
private List<LoggedMove> moves; private List<LoggedMove> moves;
private Position enPassant;
private Color activeColor; private Color activeColor;
private int fullmoveCounter, halfmoveClock;
public Log() { public Log() {
moves = new ArrayList<>(); moves = new ArrayList<>();
activeColor = Color.WHITE; reset();
}
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;
} }
@Override @Override
@ -67,23 +37,103 @@ public class Log implements Cloneable {
return log; 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 Color getActiveColor() { return activeColor; }
public void setActiveColor(Color activeColor) { this.activeColor = 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 static class LoggedMove {
public final Move move; public final Move move;
public final Piece capturedPiece; public final Piece capturedPiece;
public final Position enPassant; public final Position enPassant;
public final Color activeColor;
public final int fullmoveCounter, halfmoveClock; 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.move = move;
this.capturedPiece = capturedPiece; this.capturedPiece = capturedPiece;
this.enPassant = enPassant; this.enPassant = enPassant;
this.activeColor = activeColor;
this.fullmoveCounter = fullmoveCounter; this.fullmoveCounter = fullmoveCounter;
this.halfmoveClock = halfmoveClock; this.halfmoveClock = halfmoveClock;
} }

View File

@ -29,7 +29,7 @@ public class Pawn extends Piece {
move.type = Move.Type.PAWN_PROMOTION; move.type = Move.Type.PAWN_PROMOTION;
// Mark the move as en passant if necessary // Mark the move as en passant if necessary
if (strafe && move.dest.equals(board.getEnPassantSquare())) { if (strafe && move.dest.equals(board.getLog().getEnPassant())) {
enPassant = true; enPassant = true;
move.type = Move.Type.EN_PASSANT; move.type = Move.Type.EN_PASSANT;
} }
@ -84,8 +84,8 @@ public class Pawn extends Piece {
moves.parallelStream().forEach(m -> m.type = Move.Type.PAWN_PROMOTION); moves.parallelStream().forEach(m -> m.type = Move.Type.PAWN_PROMOTION);
// Add en passant move if necessary // Add en passant move if necessary
if (board.getEnPassantSquare() != null) { if (board.getLog().getEnPassant() != null) {
Move move = new Move(pos, board.getEnPassantSquare(), Move.Type.EN_PASSANT); Move move = new Move(pos, board.getLog().getEnPassant(), Move.Type.EN_PASSANT);
if (move.isDiagonal() && move.xDist == 1) moves.add(move); if (move.isDiagonal() && move.xDist == 1) moves.add(move);
} }

View File

@ -79,7 +79,7 @@ public class Game {
case CHECK: case CHECK:
System.out.printf("%s in check!%n", player.color.opposite()); System.out.printf("%s in check!%n", player.color.opposite());
default: default:
players.get(board.getActiveColor()).requestMove(); players.get(board.getLog().getActiveColor()).requestMove();
} }
} else player.requestMove(); } else player.requestMove();
} }
@ -111,7 +111,7 @@ public class Game {
black.setColor(Color.WHITE); black.setColor(Color.WHITE);
players.put(Color.WHITE, black); players.put(Color.WHITE, black);
players.put(Color.BLACK, white); players.put(Color.BLACK, white);
players.get(board.getActiveColor()).requestMove(); players.get(board.getLog().getActiveColor()).requestMove();
} }
public Board getBoard() { return board; } public Board getBoard() { return board; }

View File

@ -41,6 +41,6 @@ class BoardTest {
clone.getBoardArr()[0][0] = new Queen(Color.BLACK, clone); clone.getBoardArr()[0][0] = new Queen(Color.BLACK, clone);
clone.move(new Move(1, 1, 1, 2)); clone.move(new Move(1, 1, 1, 2));
assertNotEquals(clone.getBoardArr()[0][0], board.getBoardArr()[0][0]); assertNotEquals(clone.getBoardArr()[0][0], board.getBoardArr()[0][0]);
assertNotEquals(clone.getActiveColor(), board.getActiveColor()); assertNotEquals(clone.getLog().getActiveColor(), board.getLog().getActiveColor());
} }
} }