Check and Checkmate of King
This commit is contained in:
parent
b09b46607a
commit
a6f8ef9f66
|
|
@ -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,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,9 +298,26 @@ 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();
|
||||
while (true) {
|
||||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -110,4 +110,6 @@ public class Game extends Thread {
|
|||
this.activationAIFlags[isWhite?1:0] = !this.activationAIFlags[isWhite?1:0];
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue