I'm working on a chess bot for a personal project (in Java) and for the life of me, I can't figure out how to see if a piece can block a check. Here is the setup:
Board: Holds a 2d array of Squares, all of the Squares on the Board, and all of the Pieces. All of these fields are static so I didn't have to make like 80 getters. Also holds these ArrayLists: white's legal moves, black's legal moves, all of white's moves, all of black's moves, all of white's pieces, and all of black's pieces.
Square: Holds Pieces.
Piece (And its child classes): Has two ArrayLists: moveset (all of the squares it could move to on an empty board from its current position, this is how I'm going to deal with pins) and seen squares (all of the squares it can move to without hitting a piece of its own color). King has a boolean inCheck field.
Move: Takes a piece and a square, has a play() method that deals with the logic of actually moving a piece, setting the square's new piece, etc.
Logic: The Board's vision() method gets called after every move. This updates the moveset and seen squares for all of the pieces and sets the King's inCheck field. It then adds all possible moves to the all moves ArrayLists. And then it should add all of the legal moves (taking checks into account) to the legal moves ArrayLists.
Accounting for checks is where I'm having trouble. The first part of is easy: Loop through all of white's moves, and if the King is in check, the King can move, so add it to the legal list. All moves that block a check would also be added (unless that piece is pinned), and everything else would be illegal until the King gets out of check.
But how do I see if a piece can block a check? This is the last thing I have to do before I get to actually work on the bot logic which is the part I'm really excited about.
I've tried:
-Seeing if one of white's pieces sees the same square as a piece giving the check (I think this is the right approach, I just can't figure out how to do it).
-I made a method that returns an ArrayList of pieces that are giving checks, but got nowhere with that too.
Thank you for reading this! I know this was a novel lol I just wanted to make sure I gave all of the relevant information.
Here is the vision method and the get checking pieces method:
public static void vision() {
//updateBoardVision is an overridden method in all of the
//Piece subclasses. It reevaluates all theoretically possible moves
//from the current square and all the squares it can move to
for (Piece p : whitePieces) {
p.updateBoardVision();
}
for (Piece p : blackPieces) {
p.updateBoardVision();
}
//if a white piece can see the square the black king is on,
//the black king is in check
for (Piece p : whitePieces) {
if (p.seenSquares.contains(Board.bK.square)) {
Board.bK.setInCheck(true);
}
}
//and vice versa
for (Piece p : blackPieces) {
if (p.seenSquares.contains(Board.wK.square)) {
Board.wK.setInCheck(true);
}
}
//all possible moves, discounting checks
for (Piece p : whitePieces) {
for (Square s : p.seenSquares) {
Move m = new Move(p, s);
allWhiteMoves.add(m);
}
}
for (Piece p : blackPieces) {
for (Square s : p.seenSquares) {
Move m = new Move(p, s);
allBlackMoves.add(m);
}
}
//set every move to invalid
for (Move wm : allWhiteMoves) {
wm.setValid(false);
}
for (Move bm : allBlackMoves) {
bm.setValid(false);
}
for (Move aWhiteMove : allWhiteMoves) {
//if the king is in check
if (wK.isInCheck()) {
//then we can move it
if (aWhiteMove.getPiece().equals(wK)) {
aWhiteMove.setValid(true);
}
//if there is a white piece, in white moves, that
//sees the same square as a checking piece, it can
//block the check so it's valid,
//but I also need to account for double checks.
//and then i need to do the same for black
//this whole part is where I'm confused
}
}
//after that i'll add all of the legal moves
for (Move r : allWhiteMoves) {
if (r.isValid()) {
whiteLegalMoves.add(r);
}
}
for (Move s : allBlackMoves) {
if (s.isValid()) {
blackLegalMoves.add(s);
}
}
}
//this is where i see what piece(s) is/are giving the check
//it's an arraylist not a piece to account for multiple
//pieces giving a check at the same time
public static ArrayList<Piece> findCheckPieceWhite() {
ArrayList<Piece> checkPieces = new ArrayList();
for (Piece p : blackPieces) {
if (p.seenSquares.contains(wK.square)) {
checkPieces.add(p);
}
}
return checkPieces;
}
public static ArrayList<Piece> findCheckPieceBlack() {
ArrayList<Piece> checkPieces = new ArrayList();
for (Piece p : whitePieces) {
if (p.seenSquares.contains(bK.square)) {
checkPieces.add(p);
}
}
return checkPieces;
}