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

@ -19,6 +19,28 @@ public class Board {
this.pieces = new ArrayList<>();
//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
@ -112,10 +134,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,34 +218,34 @@ 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;
switch (piece.getType()) {
case Pawn:
int forwardY = y + dir;
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
moves.add(new int[]{x, forwardY});
int twoForwardY = y + 2 * dir;
boolean atStartingRank = (piece.isWhite() && y == 1) || (!piece.isWhite() && y == 6);
if (atStartingRank && isInBounds(x, twoForwardY) && getPieceAt(x, twoForwardY) == null) {
moves.add(new int[] {x, twoForwardY});
moves.add(new int[]{x, twoForwardY});
}
}
// Capture diagonally
Piece diagLeft = getPieceAt(x - 1, forwardY);
if (diagLeft != null && diagLeft.isWhite() != piece.isWhite())
moves.add(new int[] {x - 1, forwardY});
moves.add(new int[]{x - 1, forwardY});
Piece diagRight = getPieceAt(x + 1, forwardY);
if (diagRight != null && diagRight.isWhite() != piece.isWhite())
moves.add(new int[] {x + 1, forwardY});
moves.add(new int[]{x + 1, forwardY});
break;
case Rook:
@ -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();
@ -314,22 +400,6 @@ public void undoLastMove() {
selected = null;
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

@ -109,5 +109,7 @@ public class Game extends Thread {
public void toggleAI(boolean isWhite) {
this.activationAIFlags[isWhite?1:0] = !this.activationAIFlags[isWhite?1:0];
}
}

View File

@ -36,6 +36,13 @@ public class Piece {
public void setPosition(int x , int y) {
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;
}
}