Fix checkmate logic to account for other piece taking attacker

main
Elnu 2 years ago
parent 884fc44ed4
commit 36f3873816

@ -197,7 +197,18 @@ public class Board {
break;
}
}
isGameOver = inCheck && oppositeKing.getLegalMoves(oppositeKingPosition, this).size() == 0;
if (inCheck) {
isGameOver = true;
for (Move move : getAllLegalMoves(!movedPiece.black)) {
move(move);
if (!oppositeKing.isInCheck(move, this)) {
isGameOver = false;
undoMove();
break;
}
undoMove();
}
}
victor = movedPiece.black;
}
@ -287,10 +298,10 @@ public class Board {
forEachPiece((x, y, piece) -> tileAction.forEachTile(new BoardCoordinate(x, y), get(x, y)));
}
public ArrayList<Move> getAllLegalMoves() {
public ArrayList<Move> getAllLegalMoves(boolean black) {
ArrayList<Move> allLegalMoves = new ArrayList<>();
forEachPiece((from, piece) -> {
if (!piece.black) return;
if (piece.black != black) return;
ArrayList<BoardCoordinate> legalTiles = piece.getLegalMoves(from, this);
for (BoardCoordinate to : legalTiles) {
allLegalMoves.add(new Move(from, to));

@ -5,7 +5,7 @@ public class ChessAI {
int bestScore = Integer.MIN_VALUE;
Move bestMove = null;
for (Move move : board.getAllLegalMoves()) {
for (Move move : board.getAllLegalMoves(true)) {
board.move(move);
int score = minimax(board, MAX_DEPTH, Integer.MIN_VALUE, Integer.MAX_VALUE, false);
board.undoMove();
@ -27,7 +27,7 @@ public class ChessAI {
int score;
if (maximizingPlayer) {
score = Integer.MIN_VALUE;
for (Move move : board.getAllLegalMoves()) {
for (Move move : board.getAllLegalMoves(true)) {
board.move(move);
score = Math.max(score, minimax(board, depth - 1, alpha, beta, false));
board.undoMove();
@ -38,7 +38,7 @@ public class ChessAI {
}
} else {
score = Integer.MAX_VALUE;
for (Move move : board.getAllLegalMoves()) {
for (Move move : board.getAllLegalMoves(true)) {
board.move(move);
score = Math.min(score, minimax(board, depth - 1, alpha, beta, true));
board.undoMove();

@ -38,7 +38,7 @@ public abstract class Piece {
possibleMove.y >= Board.BOARD_SIZE ||
// is in check
(doCheckChecks && isInCheck(position, possibleMove, board))
(doCheckChecks && isInCheck(new Move(position, possibleMove), board))
) {
legalMoves.remove(i);
i--;
@ -48,16 +48,16 @@ public abstract class Piece {
return legalMoves;
}
boolean isInCheck(BoardCoordinate from, BoardCoordinate to, Board board) {
boolean isInCheck(Move move, Board board) {
boolean isInCheck = false;
board.move(from, to);
board.move(move);
outer: for (int y = 0; y < Board.BOARD_SIZE; y++) {
for (int x = 0; x < Board.BOARD_SIZE; x++) {
Piece piece = board.get(x, y);
if (piece == null || piece.black == black) continue;
ArrayList<BoardCoordinate> legalMoves = piece.getLegalMoves(new BoardCoordinate(x, y), board, false);
for (BoardCoordinate move : legalMoves) {
Piece pieceAtMove = board.get(move);
for (BoardCoordinate legalMove : legalMoves) {
Piece pieceAtMove = board.get(legalMove);
if (pieceAtMove instanceof King) {
isInCheck = true;
break outer;