Add repetition detection
This commit is contained in:
@@ -244,6 +244,14 @@ impl Game {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn in_repetition(&self) -> bool {
|
||||
if self.board.state.halfmove_clock < 4 {
|
||||
return false;
|
||||
}
|
||||
|
||||
self.history.in_repetition(self.hash)
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Game {
|
||||
@@ -431,4 +439,23 @@ mod tests {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_in_repetition() -> Result<(), String> {
|
||||
let mut game = from_fen(FEN)?;
|
||||
|
||||
game.make_move(&Move::new(Square::F3, Square::E3));
|
||||
game.make_move(&Move::new(Square::F7, Square::G7));
|
||||
game.make_move(&Move::new(Square::E3, Square::F3));
|
||||
game.make_move(&Move::new(Square::G7, Square::F7));
|
||||
game.make_move(&Move::new(Square::F3, Square::E3));
|
||||
|
||||
assert!(game.in_repetition());
|
||||
|
||||
game.make_move(&Move::new(Square::H7, Square::H6));
|
||||
|
||||
assert!(!game.in_repetition());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,15 @@ impl History {
|
||||
pub fn pop_move_parameters(&mut self) -> Option<MoveParameters> {
|
||||
self.move_parameters.pop()
|
||||
}
|
||||
|
||||
pub fn in_repetition(&self, hash: ZobristHash) -> bool {
|
||||
self.move_parameters
|
||||
.iter()
|
||||
.rev()
|
||||
.skip(1)
|
||||
.step_by(2)
|
||||
.any(|mp| mp.zobrist_hash.expect("State without hash") == hash)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
|
||||
@@ -24,6 +24,10 @@ pub fn negamax(
|
||||
bail!("Time is up! In Negamax");
|
||||
}
|
||||
|
||||
if plies != 0 && game.in_repetition() {
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
if depth == 0 {
|
||||
let q_score = quiescence(game, alpha, beta, time_info).map_err(|e| anyhow!("{e}"))?;
|
||||
return Ok(q_score);
|
||||
|
||||
Reference in New Issue
Block a user