[moves] Revoke castling rights when King and Rook make moves of their starting squares
When the King moves, revoke all rights for the moving player. When the rook moves, revoke castling rights for that side of the board, if it's moving off its starting square.
This commit is contained in:
		
							parent
							
								
									d73630c85e
								
							
						
					
					
						commit
						c7b9544004
					
				
					 1 changed files with 43 additions and 12 deletions
				
			
		|  | @ -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<MoveRecord, MakeMoveError>; | ||||
|  | @ -83,6 +83,8 @@ trait MakeMoveInternal { | |||
| 
 | ||||
|     fn advance_board_state( | ||||
|         &mut self, | ||||
|         ply: &Move, | ||||
|         piece_moved: &Piece, | ||||
|         en_passant_target: Option<Square>, | ||||
|         half_move_clock: HalfMoveClock, | ||||
|     ); | ||||
|  | @ -151,7 +153,7 @@ impl<T: BoardProvider> 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<T: BoardProvider> 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<T: BoardProvider> 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<T: BoardProvider> 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<T: BoardProvider> 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<Square>, | ||||
|         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; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue