diff --git a/moves/src/make_move.rs b/moves/src/make_move.rs index 38b03cf..7b8fd33 100644 --- a/moves/src/make_move.rs +++ b/moves/src/make_move.rs @@ -2,10 +2,10 @@ use crate::{Move, MoveRecord}; use chessfriend_board::{ - castle::CastleEvaluationError, movement::Movement, Board, BoardProvider, PlacePieceError, - PlacePieceStrategy, + Board, BoardProvider, CastleParameters, PlacePieceError, PlacePieceStrategy, + castle::CastleEvaluationError, movement::Movement, }; -use chessfriend_core::{Color, Piece, Rank, Square, Wing}; +use chessfriend_core::{Color, Piece, Rank, Shape, Square, Wing}; use thiserror::Error; pub type MakeMoveResult = Result; @@ -83,6 +83,8 @@ trait MakeMoveInternal { fn advance_board_state( &mut self, + ply: &Move, + piece_moved: &Piece, en_passant_target: Option, half_move_clock: HalfMoveClock, ); @@ -151,7 +153,7 @@ impl MakeMoveInternal for T { let record = MoveRecord::new(board, ply, None); - self.advance_board_state(None, HalfMoveClock::Advance); + self.advance_board_state(&ply, &piece, None, HalfMoveClock::Advance); Ok(record) } @@ -179,7 +181,12 @@ impl MakeMoveInternal for T { _ => unreachable!(), }; - self.advance_board_state(Some(en_passant_target), HalfMoveClock::Advance); + self.advance_board_state( + &ply, + &piece, + Some(en_passant_target), + HalfMoveClock::Advance, + ); Ok(record) } @@ -221,7 +228,7 @@ impl MakeMoveInternal for T { let record = MoveRecord::new(board, ply, Some(captured_piece)); - self.advance_board_state(None, HalfMoveClock::Reset); + self.advance_board_state(&ply, &piece, None, HalfMoveClock::Reset); Ok(record) } @@ -246,7 +253,7 @@ impl MakeMoveInternal for T { board.revoke_castling_right_unwrapped(active_color, wing); - self.advance_board_state(None, HalfMoveClock::Advance); + self.advance_board_state(&ply, &king, None, HalfMoveClock::Advance); Ok(record) } @@ -280,28 +287,52 @@ impl MakeMoveInternal for T { let record = MoveRecord::new(board, ply, None); - self.advance_board_state(None, HalfMoveClock::Reset); + self.advance_board_state(&ply, &piece, None, HalfMoveClock::Reset); Ok(record) } fn advance_board_state( &mut self, + ply: &Move, + piece_moved: &Piece, en_passant_target: Option, half_move_clock: HalfMoveClock, ) { let board = self.board_mut(); - match half_move_clock { - HalfMoveClock::Reset => board.half_move_clock = 0, - HalfMoveClock::Advance => board.half_move_clock += 1, + board.set_en_passant_target_option(en_passant_target); + + match piece_moved.shape { + Shape::Rook => { + let origin = ply.origin_square(); + + if board.color_has_castling_right(None, Wing::KingSide) { + let kingside_parameters = + CastleParameters::get(board.active_color(), Wing::KingSide); + if origin == kingside_parameters.origin.rook { + board.revoke_castling_right(None, Wing::KingSide); + } + } + + let queenside_parameters = + CastleParameters::get(board.active_color(), Wing::QueenSide); + if origin == queenside_parameters.origin.rook { + board.revoke_castling_right(None, Wing::QueenSide); + } + } + Shape::King => board.revoke_all_castling_rights(), + _ => {} } let previous_active_color = board.active_color(); let active_color = previous_active_color.next(); board.set_active_color(active_color); - board.set_en_passant_target_option(en_passant_target); + match half_move_clock { + HalfMoveClock::Reset => board.half_move_clock = 0, + HalfMoveClock::Advance => board.half_move_clock += 1, + } if active_color == Color::White { board.full_move_number += 1;