tune: make only three repetitions (not two) evaluate as draw

this commit might fix some positions being evaluated as zero
This commit is contained in:
dogeystamp 2024-12-25 20:08:32 -05:00
parent e06d614885
commit 093dc51eed
No known key found for this signature in database
3 changed files with 31 additions and 33 deletions

View File

@ -568,17 +568,6 @@ impl BoardHistory {
self.ptr_start += 1;
}
}
/// Remove from end (pop) hash from history.
///
/// Adding and then removing a hash may erase old entries due to lack of space.
fn pop(&mut self) {
if self.ptr_end == self.ptr_start {
// history is empty already
} else {
self.ptr_end -= 1;
}
}
}
/// Game state, describes a position.
@ -810,7 +799,7 @@ mod tests {
use super::*;
use fen::FromFen;
use movegen::{FromUCIAlgebraic, Move};
use movegen::{FromUCIAlgebraic, Move, ToUCIAlgebraic};
#[test]
fn test_square_casts() {
@ -962,22 +951,6 @@ mod tests {
assert_eq!(history.count(board_empty.zobrist), 4);
assert_eq!(history.count(board.zobrist), HISTORY_SIZE - 5);
for _ in 0..3 {
history.pop();
}
assert_eq!(history.count(board_empty.zobrist), 1);
// after popping, the replaced entries no longer exist
assert_eq!(history.count(board.zobrist), HISTORY_SIZE - 5);
history.pop();
assert_eq!(history.count(board_empty.zobrist), 0);
assert_eq!(history.count(board.zobrist), HISTORY_SIZE - 5);
history.pop();
assert_eq!(history.count(board_empty.zobrist), 0);
assert_eq!(history.count(board.zobrist), HISTORY_SIZE - 6);
}
#[test]
@ -992,6 +965,7 @@ mod tests {
for _ in 0..2 {
for mv in &mvs {
board.push_history();
let _ = mv.make(&mut board);
}
}
@ -1015,10 +989,17 @@ mod tests {
let expected_bestmv = Move::from_uci_algebraic("a2a1").unwrap();
let mut cnt = 0;
for mv in &mvs {
board.push_history();
cnt += 1;
let _ = mv.make(&mut board);
}
eprintln!("board is: '{}'", board.to_fen());
eprintln!("added {} history entries", cnt);
let (_tx, rx) = std::sync::mpsc::channel();
let cache = TranspositionTable::new(1);
@ -1037,7 +1018,20 @@ mod tests {
let (line, eval) = best_line(&mut board, &mut engine_state);
let best_mv = line.last().unwrap();
assert_eq!(*best_mv, expected_bestmv);
expected_bestmv.make(&mut board);
eprintln!(
"after expected mv, board repeated {} times",
board.history.count(board.zobrist)
);
assert_eq!(
*best_mv,
expected_bestmv,
"got {} (eval {:?}) instead of {}",
best_mv.to_uci_algebraic(),
eval,
expected_bestmv.to_uci_algebraic()
);
assert!(EvalInt::from(eval) == 0);
// now ensure that it's completely one-sided without the repetition opportunity

View File

@ -63,8 +63,8 @@ fn cmd_position_moves(mut tokens: std::str::SplitWhitespace<'_>, mut board: Boar
"moves" => {
for mv in tokens.by_ref() {
let mv = Move::from_uci_algebraic(mv).unwrap();
let _ = mv.make(&mut board);
board.push_history();
let _ = mv.make(&mut board);
}
}
_ => ignore!(),

View File

@ -208,14 +208,18 @@ fn minmax(board: &mut Board, state: &mut EngineState, mm: MinmaxState) -> (Vec<M
}
}
let is_drawn = !mm.quiesce && board.history.count(board.zobrist) >= 1;
let is_repetition_draw = board.history.count(board.zobrist) >= 2;
// quiescence stand-pat score (only calculated if needed).
// this is where static eval goes.
let mut board_eval: Option<EvalInt> = None;
if mm.quiesce {
board_eval = Some(board.eval() * EvalInt::from(board.turn.sign()));
board_eval = Some(if is_repetition_draw {
0
} else {
board.eval() * EvalInt::from(board.turn.sign())
});
}
if mm.depth == 0 {
@ -343,7 +347,7 @@ fn minmax(board: &mut Board, state: &mut EngineState, mm: MinmaxState) -> (Vec<M
}
}
if is_drawn {
if is_repetition_draw {
abs_best = SearchEval::Exact(0);
}