Check and Checkmate of King

This commit is contained in:
Yash Shah 2025-05-13 22:30:22 +02:00
parent b09b46607a
commit a6f8ef9f66
3 changed files with 107 additions and 28 deletions

View File

@ -20,6 +20,28 @@ public class Board {
//TODO
}
public Board(Board other) {
this.width = other.width;
this.height = other.height;
this.turnNumber = other.turnNumber;
this.turnWhite = other.turnWhite;
this.selected = other.selected != null ? new int[]{other.selected[0], other.selected[1]} : null;
this.pieces = new ArrayList<>();
for (Piece p : other.pieces) {
this.pieces.add(new Piece(p)); // uses Piece copy constructor (next step)
}
this.highlighted = new ArrayList<>();
for (int[] pos : other.highlighted) {
this.highlighted.add(new int[]{pos[0], pos[1]});
}
this.moveHistory = new ArrayList<>(other.moveHistory);
}
public int getWidth() {
//TODO
return width;
@ -113,10 +135,57 @@ public class Board {
return sb.toString();
}
public ArrayList<Piece> getPieces() {
return pieces;
}
public Piece getKing(boolean isWhite) {
for (Piece p : pieces) {
if (p.isWhite() == isWhite && p.getType() == PieceType.King) {
return p;
}
}
return null;
}
public boolean isInCheck(boolean whitePlayer) {
Piece king = getKing(whitePlayer);
if (king == null) return false;
int kingX = king.getX();
int kingY = king.getY();
for (Piece piece : pieces) {
if (piece.isWhite() != whitePlayer) {
ArrayList<int[]> enemyMoves = getLegalMoves(piece, false); // disable check validation
for (int[] move : enemyMoves) {
if (move[0] == kingX && move[1] == kingY) {
return true;
}
}
}
}
return false;
}
public boolean isCheckmate(boolean whitePlayer) {
if (!isInCheck(whitePlayer)) return false;
for (Piece p : pieces) {
if (p.isWhite() == whitePlayer) {
ArrayList<int[]> legalMoves = getLegalMoves(p);
if (!legalMoves.isEmpty()) return false;
}
}
return true;
}
public void userTouch(int x, int y) {
Piece clickedPiece = getPieceAt(x, y);
@ -149,6 +218,10 @@ public class Board {
public ArrayList<int[]> getLegalMoves(Piece piece) {
return getLegalMoves(piece, true); // default: check for king safety
}
public ArrayList<int[]> getLegalMoves(Piece piece, boolean validateCheck) {
ArrayList<int[]> moves = new ArrayList<>();
int x = piece.getX(), y = piece.getY();
int dir = piece.isWhite() ? 1 : -1;
@ -157,11 +230,8 @@ public class Board {
case Pawn:
int forwardY = y + dir;
// Move one square forward if it's empty
if (isInBounds(x, forwardY) && getPieceAt(x, forwardY) == null) {
moves.add(new int[]{x, forwardY});
// Move two squares forward if at starting position and both squares are empty
int twoForwardY = y + 2 * dir;
boolean atStartingRank = (piece.isWhite() && y == 1) || (!piece.isWhite() && y == 6);
if (atStartingRank && isInBounds(x, twoForwardY) && getPieceAt(x, twoForwardY) == null) {
@ -169,7 +239,6 @@ public class Board {
}
}
// Capture diagonally
Piece diagLeft = getPieceAt(x - 1, forwardY);
if (diagLeft != null && diagLeft.isWhite() != piece.isWhite())
moves.add(new int[]{x - 1, forwardY});
@ -229,8 +298,25 @@ public class Board {
}
break;
}
return moves;
if (!validateCheck) return moves;
// Filter out moves that put own king in check
ArrayList<int[]> legalMoves = new ArrayList<>();
for (int[] move : moves) {
Board copy = new Board(this);
Piece p = copy.getPieceAt(x, y);
Piece captured = copy.getPieceAt(move[0], move[1]);
Move testMove = new Move(p, x, y, move[0], move[1], captured);
copy.playMove(testMove);
if (!copy.isInCheck(piece.isWhite())) {
legalMoves.add(move);
}
}
return legalMoves;
}
private void addLinearMoves(ArrayList<int[]> moves, Piece piece, int dx, int dy) {
int x = piece.getX(), y = piece.getY();
@ -315,22 +401,6 @@ public void undoLastMove() {
highlighted.clear();
}
public Board(Board board) {
if (moveHistory.isEmpty()) return;
Move lastMove = moveHistory.remove(moveHistory.size() - 1);
Piece movedPiece = lastMove.getPieceMoved();
movedPiece.setPosition(lastMove.getFromX(), lastMove.getFromY());
if (lastMove.getPieceCaptured() != null) {
pieces.add(lastMove.getPieceCaptured());
}
turnWhite = !turnWhite;
turnNumber--;
}
public void playMove(Move move) {
Piece piece = move.getPieceMoved();

View File

@ -110,4 +110,6 @@ public class Game extends Thread {
this.activationAIFlags[isWhite?1:0] = !this.activationAIFlags[isWhite?1:0];
}
}

View File

@ -37,5 +37,12 @@ public class Piece {
this.x=x;
this.y=y;
}
public Piece(Piece other) {
this.isWhite = other.isWhite;
this.type = other.type;
this.x = other.x;
this.y = other.y;
}
}