From 9507432bd3572d8a2c55e4c2b2974a3fb2f2dc4f Mon Sep 17 00:00:00 2001 From: Bruno BELANYI Date: Fri, 5 Apr 2024 23:35:46 +0100 Subject: [PATCH 1/2] Modify castling rights after rook capture --- src/board/chess_board/mod.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/board/chess_board/mod.rs b/src/board/chess_board/mod.rs index 33a5580..ba010d4 100644 --- a/src/board/chess_board/mod.rs +++ b/src/board/chess_board/mod.rs @@ -185,6 +185,13 @@ impl ChessBoard { *self.piece_occupancy_mut(piece) ^= chess_move.destination(); *self.color_occupancy_mut(opponent) ^= chess_move.destination(); self.combined_occupancy ^= chess_move.destination(); + // If a rook is captured, it loses its castling rights + let castle_rights = self.castle_rights_mut(opponent); + *castle_rights = match (piece, chess_move.destination().file()) { + (Piece::Rook, File::A) => castle_rights.without_queen_side(), + (Piece::Rook, File::H) => castle_rights.without_king_side(), + _ => *castle_rights, + }; } // Revertible state modification @@ -768,6 +775,17 @@ mod test { ); } + #[test] + fn do_move_capture_changes_castling() { + let mut position = ChessBoard::from_fen("r3k2r/8/8/8/8/8/8/R3K2R w KQkq - 0 1").unwrap(); + let expected = ChessBoard::from_fen("r3k2R/8/8/8/8/8/8/R3K3 b Qq - 0 1").unwrap(); + + let capture = Move::new(Square::H1, Square::H8, None); + + position.do_move(capture); + assert_eq!(position, expected); + } + #[test] fn do_move_and_undo() { // Start from default position From f9ba6fa68090f7266163c08fcf3efd7f4f14c732 Mon Sep 17 00:00:00 2001 From: Bruno BELANYI Date: Sat, 6 Apr 2024 00:20:09 +0100 Subject: [PATCH 2/2] Refactor castling right management in 'do_move' I find it more readable. --- src/board/chess_board/mod.rs | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/board/chess_board/mod.rs b/src/board/chess_board/mod.rs index ba010d4..c594adf 100644 --- a/src/board/chess_board/mod.rs +++ b/src/board/chess_board/mod.rs @@ -170,17 +170,13 @@ impl ChessBoard { } else { self.en_passant = None; } - if move_piece == Piece::King { - *self.castle_rights_mut(self.current_player()) = CastleRights::NoSide; - } - if move_piece == Piece::Rook { - let castle_rights = self.castle_rights_mut(self.current_player()); - *castle_rights = match chess_move.start().file() { - File::A => castle_rights.without_queen_side(), - File::H => castle_rights.without_king_side(), - _ => *castle_rights, - } - } + let castle_rights = self.castle_rights_mut(self.current_player()); + *castle_rights = match (move_piece, chess_move.start().file()) { + (Piece::Rook, File::A) => castle_rights.without_queen_side(), + (Piece::Rook, File::H) => castle_rights.without_king_side(), + (Piece::King, _) => CastleRights::NoSide, + _ => *castle_rights, + }; if let Some(piece) = captured_piece { *self.piece_occupancy_mut(piece) ^= chess_move.destination(); *self.color_occupancy_mut(opponent) ^= chess_move.destination();