[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 crate::{Move, MoveRecord};
|
||||||
use chessfriend_board::{
|
use chessfriend_board::{
|
||||||
castle::CastleEvaluationError, movement::Movement, Board, BoardProvider, PlacePieceError,
|
Board, BoardProvider, CastleParameters, PlacePieceError, PlacePieceStrategy,
|
||||||
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;
|
use thiserror::Error;
|
||||||
|
|
||||||
pub type MakeMoveResult = Result<MoveRecord, MakeMoveError>;
|
pub type MakeMoveResult = Result<MoveRecord, MakeMoveError>;
|
||||||
|
@ -83,6 +83,8 @@ trait MakeMoveInternal {
|
||||||
|
|
||||||
fn advance_board_state(
|
fn advance_board_state(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
ply: &Move,
|
||||||
|
piece_moved: &Piece,
|
||||||
en_passant_target: Option<Square>,
|
en_passant_target: Option<Square>,
|
||||||
half_move_clock: HalfMoveClock,
|
half_move_clock: HalfMoveClock,
|
||||||
);
|
);
|
||||||
|
@ -151,7 +153,7 @@ impl<T: BoardProvider> MakeMoveInternal for T {
|
||||||
|
|
||||||
let record = MoveRecord::new(board, ply, None);
|
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)
|
Ok(record)
|
||||||
}
|
}
|
||||||
|
@ -179,7 +181,12 @@ impl<T: BoardProvider> MakeMoveInternal for T {
|
||||||
_ => unreachable!(),
|
_ => 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)
|
Ok(record)
|
||||||
}
|
}
|
||||||
|
@ -221,7 +228,7 @@ impl<T: BoardProvider> MakeMoveInternal for T {
|
||||||
|
|
||||||
let record = MoveRecord::new(board, ply, Some(captured_piece));
|
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)
|
Ok(record)
|
||||||
}
|
}
|
||||||
|
@ -246,7 +253,7 @@ impl<T: BoardProvider> MakeMoveInternal for T {
|
||||||
|
|
||||||
board.revoke_castling_right_unwrapped(active_color, wing);
|
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)
|
Ok(record)
|
||||||
}
|
}
|
||||||
|
@ -280,28 +287,52 @@ impl<T: BoardProvider> MakeMoveInternal for T {
|
||||||
|
|
||||||
let record = MoveRecord::new(board, ply, None);
|
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)
|
Ok(record)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn advance_board_state(
|
fn advance_board_state(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
ply: &Move,
|
||||||
|
piece_moved: &Piece,
|
||||||
en_passant_target: Option<Square>,
|
en_passant_target: Option<Square>,
|
||||||
half_move_clock: HalfMoveClock,
|
half_move_clock: HalfMoveClock,
|
||||||
) {
|
) {
|
||||||
let board = self.board_mut();
|
let board = self.board_mut();
|
||||||
|
|
||||||
match half_move_clock {
|
board.set_en_passant_target_option(en_passant_target);
|
||||||
HalfMoveClock::Reset => board.half_move_clock = 0,
|
|
||||||
HalfMoveClock::Advance => board.half_move_clock += 1,
|
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 previous_active_color = board.active_color();
|
||||||
let active_color = previous_active_color.next();
|
let active_color = previous_active_color.next();
|
||||||
board.set_active_color(active_color);
|
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 {
|
if active_color == Color::White {
|
||||||
board.full_move_number += 1;
|
board.full_move_number += 1;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue