[moves] Make sure en passant state is cleared after making moves

En passant state should be cleared after any move that isn't a double push.

To support this fix, rename advance_clocks to advance_board_state and let it take
an Option<Square>. Every supporting make_move method calls this method to update
board state when the make is done. So this is the ideal place to also update
e.p. state.
This commit is contained in:
Eryn Wells 2025-06-07 20:08:25 -07:00
parent e2ce778247
commit 638ef5e66a

View file

@ -81,7 +81,11 @@ trait MakeMoveInternal {
fn validate_move(&self, ply: Move, validate: ValidateMove) -> Result<(), MakeMoveError>;
fn validate_active_piece(&self, ply: Move) -> Result<Piece, MakeMoveError>;
fn advance_clocks(&mut self, half_move_clock: HalfMoveClock);
fn advance_board_state(
&mut self,
en_passant_target: Option<Square>,
half_move_clock: HalfMoveClock,
);
}
impl<T: BoardProvider> MakeMove for T {
@ -147,7 +151,7 @@ impl<T: BoardProvider> MakeMoveInternal for T {
let record = MoveRecord::new(board, ply, None);
self.advance_clocks(HalfMoveClock::Advance);
self.advance_board_state(None, HalfMoveClock::Advance);
Ok(record)
}
@ -169,13 +173,13 @@ impl<T: BoardProvider> MakeMoveInternal for T {
// board state before the change is preserved.
let record = MoveRecord::new(board, ply, None);
board.set_en_passant_target(match target.rank() {
let en_passant_target = match target.rank() {
Rank::FOUR => Square::from_file_rank(target.file(), Rank::THREE),
Rank::FIVE => Square::from_file_rank(target.file(), Rank::SIX),
_ => unreachable!(),
});
};
self.advance_clocks(HalfMoveClock::Advance);
self.advance_board_state(Some(en_passant_target), HalfMoveClock::Advance);
Ok(record)
}
@ -217,7 +221,7 @@ impl<T: BoardProvider> MakeMoveInternal for T {
let record = MoveRecord::new(board, ply, Some(captured_piece));
self.advance_clocks(HalfMoveClock::Reset);
self.advance_board_state(None, HalfMoveClock::Reset);
Ok(record)
}
@ -242,7 +246,7 @@ impl<T: BoardProvider> MakeMoveInternal for T {
board.revoke_castling_right(active_color, wing);
self.advance_clocks(HalfMoveClock::Advance);
self.advance_board_state(None, HalfMoveClock::Advance);
Ok(record)
}
@ -276,12 +280,16 @@ impl<T: BoardProvider> MakeMoveInternal for T {
let record = MoveRecord::new(board, ply, None);
self.advance_clocks(HalfMoveClock::Reset);
self.advance_board_state(None, HalfMoveClock::Reset);
Ok(record)
}
fn advance_clocks(&mut self, half_move_clock: HalfMoveClock) {
fn advance_board_state(
&mut self,
en_passant_target: Option<Square>,
half_move_clock: HalfMoveClock,
) {
let board = self.board_mut();
match half_move_clock {
@ -293,6 +301,8 @@ impl<T: BoardProvider> MakeMoveInternal for T {
let active_color = previous_active_color.next();
board.set_active_color(active_color);
board.set_en_passant_target_option(en_passant_target);
if active_color == Color::White {
board.full_move_number += 1;
}