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; 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; victor = movedPiece.black;
} }
@ -287,10 +298,10 @@ public class Board {
forEachPiece((x, y, piece) -> tileAction.forEachTile(new BoardCoordinate(x, y), get(x, y))); 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<>(); ArrayList<Move> allLegalMoves = new ArrayList<>();
forEachPiece((from, piece) -> { forEachPiece((from, piece) -> {
if (!piece.black) return; if (piece.black != black) return;
ArrayList<BoardCoordinate> legalTiles = piece.getLegalMoves(from, this); ArrayList<BoardCoordinate> legalTiles = piece.getLegalMoves(from, this);
for (BoardCoordinate to : legalTiles) { for (BoardCoordinate to : legalTiles) {
allLegalMoves.add(new Move(from, to)); allLegalMoves.add(new Move(from, to));

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

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