Test for opponent being in check during validation

This commit is contained in:
Bruno BELANYI 2022-07-30 11:58:18 +02:00
parent 58d8743106
commit f582a76e70

View file

@ -278,10 +278,48 @@ impl ChessBoard {
return false;
}
// FIXME: check for opponent being in check.
// Check that the opponent is not currently in check.
if !self.compute_checkers(!self.current_player()).is_empty() {
return false;
}
true
}
/// Compute all pieces that are currently threatening the given [Color]'s king.
fn compute_checkers(&self, color: Color) -> Bitboard {
// Unwrap is fine, there should always be exactly one king per color
let king = (self.occupancy(Piece::King, color)).try_into().unwrap();
let opponent = !color;
// No need to remove our pieces from the generated moves, we just want to check if we
// intersect with the opponent's pieces, rather than generate only valid moves.
let bishops = {
let queens = self.occupancy(Piece::Queen, opponent);
let bishops = self.occupancy(Piece::Bishop, opponent);
let bishop_attacks = movegen::bishop_moves(king, self.combined_occupancy());
(queens | bishops) & bishop_attacks
};
let rooks = {
let queens = self.occupancy(Piece::Queen, opponent);
let rooks = self.occupancy(Piece::Rook, opponent);
let rook_attacks = movegen::rook_moves(king, self.combined_occupancy());
(queens | rooks) & rook_attacks
};
let knights = {
let knights = self.occupancy(Piece::Knight, opponent);
let knight_attacks = movegen::knight_moves(king);
knights & knight_attacks
};
let pawns = {
let pawns = self.occupancy(Piece::Pawn, opponent);
let pawn_attacks = movegen::pawn_attacks(color, king);
pawns & pawn_attacks
};
bishops | rooks | knights | pawns
}
}
/// Use the starting position as a default value, corresponding to the
@ -657,6 +695,34 @@ mod test {
assert!(!position.is_valid());
}
#[test]
fn invalid_opponent_in_check() {
let position = ChessBoard {
piece_occupancy: [
// King
Square::E1 | Square::E8,
// Queen
Square::E7.into_bitboard(),
// Rook
Bitboard::EMPTY,
// Bishop
Bitboard::EMPTY,
// Knight
Bitboard::EMPTY,
// Pawn
Bitboard::EMPTY,
],
color_occupancy: [Square::E1 | Square::E7, Square::E8.into_bitboard()],
combined_occupancy: Square::E1 | Square::E7 | Square::E8,
castle_rights: [CastleRights::NoSide; 2],
en_passant: None,
half_move_clock: 0,
total_plies: 0,
side: Color::White,
};
assert!(!position.is_valid());
}
#[test]
fn fen_default_position() {
let default_position = ChessBoard::default();