Validate en-passant square's rank in 'ChessBoard'

This commit is contained in:
Bruno BELANYI 2024-04-01 21:54:32 +01:00
parent 62c2be48c4
commit ff7bea0508
2 changed files with 14 additions and 4 deletions

View file

@ -9,7 +9,7 @@ pub enum InvalidError {
InvalidPawnPosition, InvalidPawnPosition,
/// Castling rights do not match up with the state of the board. /// Castling rights do not match up with the state of the board.
InvalidCastlingRights, InvalidCastlingRights,
/// En-passant target square is not empty and behind an opponent's pawn. /// En-passant target square is not empty, behind an opponent's pawn, on the correct rank.
InvalidEnPassant, InvalidEnPassant,
/// The two kings are next to each other. /// The two kings are next to each other.
NeighbouringKings, NeighbouringKings,
@ -33,7 +33,7 @@ impl std::fmt::Display for InvalidError {
"Castling rights do not match up with the state of the board." "Castling rights do not match up with the state of the board."
} }
Self::InvalidEnPassant => { Self::InvalidEnPassant => {
"En-passant target square is not empty and behind an opponent's pawn." "En-passant target square is not empty, behind an opponent's pawn, on the correct rank."
} }
Self::NeighbouringKings => "The two kings are next to each other.", Self::NeighbouringKings => "The two kings are next to each other.",
Self::OpponentInCheck => "The opponent is currently in check.", Self::OpponentInCheck => "The opponent is currently in check.",

View file

@ -297,12 +297,22 @@ impl ChessBoard {
} }
} }
// The current en-passant target square must be empty, right behind an opponent's pawn. // En-passant validation
if let Some(square) = self.en_passant() { if let Some(square) = self.en_passant() {
// Must be empty
if !(self.combined_occupancy() & square).is_empty() { if !(self.combined_occupancy() & square).is_empty() {
return Err(InvalidError::InvalidEnPassant); return Err(InvalidError::InvalidEnPassant);
} }
let opponent_pawns = self.occupancy(Piece::Pawn, !self.current_player());
let opponent = !self.current_player();
// Must be on the opponent's third rank
if (square & opponent.third_rank().into_bitboard()).is_empty() {
return Err(InvalidError::InvalidEnPassant);
}
// Must be behind a pawn
let opponent_pawns = self.occupancy(Piece::Pawn, opponent);
let double_pushed_pawn = self let double_pushed_pawn = self
.current_player() .current_player()
.backward_direction() .backward_direction()