fix: transposition table no longer instantly returns a result
this has issues like cutting off the PV line, and more importantly, bypassing draw by repetition detection.
This commit is contained in:
parent
f6bf1b46c7
commit
9995f13693
@ -262,37 +262,61 @@ fn minmax(board: &mut Board, state: &mut EngineState, mm: MinmaxState) -> (Vec<M
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// default to worst, then gradually improve
|
enum MoveGenerator {
|
||||||
let mut alpha = mm.alpha.unwrap_or(EVAL_WORST);
|
/// Use heavily pruned search to generate moves leading to a quiet position.
|
||||||
// our best is their worst
|
Quiescence,
|
||||||
let beta = mm.beta.unwrap_or(EVAL_BEST);
|
/// Generate all legal moves.
|
||||||
|
Normal,
|
||||||
let mvs = if mm.quiesce {
|
/// Only evaluate a single move.
|
||||||
board.gen_captures().into_iter().collect::<Vec<_>>()
|
None,
|
||||||
|
}
|
||||||
|
let mut move_generator = if mm.quiesce {
|
||||||
|
MoveGenerator::Quiescence
|
||||||
} else {
|
} else {
|
||||||
board.gen_moves().into_iter().collect::<Vec<_>>()
|
MoveGenerator::Normal
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let mut trans_table_move: Option<Move> = None;
|
||||||
|
|
||||||
|
// get transposition table entry
|
||||||
|
if state.config.enable_trans_table {
|
||||||
|
if let Some(entry) = &state.cache[board.zobrist] {
|
||||||
|
trans_table_move = Some(entry.best_move);
|
||||||
|
if entry.is_qsearch == mm.quiesce && entry.depth >= mm.depth {
|
||||||
|
if let SearchEval::Exact(_) | SearchEval::Upper(_) = entry.eval {
|
||||||
|
// at this point, we could just return the best move + eval given, but this
|
||||||
|
// bypasses the draw by repetition checks in `minmax`. so just don't generate
|
||||||
|
// any other moves than the best move.
|
||||||
|
move_generator = MoveGenerator::None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mvs = match move_generator {
|
||||||
|
MoveGenerator::Quiescence => board.gen_captures().into_iter().collect::<Vec<_>>(),
|
||||||
|
MoveGenerator::Normal => board.gen_moves().into_iter().collect::<Vec<_>>(),
|
||||||
|
MoveGenerator::None => Vec::new(),
|
||||||
|
};
|
||||||
|
|
||||||
let mut mvs: Vec<_> = mvs
|
let mut mvs: Vec<_> = mvs
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|mv| (move_priority(board, &mv, state), mv))
|
.map(|mv| (move_priority(board, &mv, state), mv))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
// get transposition table entry
|
if let Some(trans_table_move) = trans_table_move {
|
||||||
if state.config.enable_trans_table {
|
mvs.push((EVAL_BEST, trans_table_move))
|
||||||
if let Some(entry) = &state.cache[board.zobrist] {
|
|
||||||
if entry.is_qsearch == mm.quiesce && entry.depth >= mm.depth {
|
|
||||||
if let SearchEval::Exact(_) | SearchEval::Upper(_) = entry.eval {
|
|
||||||
// no point looking for a better move
|
|
||||||
return (vec![entry.best_move], entry.eval);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mvs.push((EVAL_BEST, entry.best_move));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// sort moves by decreasing priority
|
// sort moves by decreasing priority
|
||||||
mvs.sort_unstable_by_key(|mv| -mv.0);
|
mvs.sort_unstable_by_key(|mv| -mv.0);
|
||||||
|
|
||||||
|
|
||||||
|
// default to worst, then gradually improve
|
||||||
|
let mut alpha = mm.alpha.unwrap_or(EVAL_WORST);
|
||||||
|
// our best is their worst
|
||||||
|
let beta = mm.beta.unwrap_or(EVAL_BEST);
|
||||||
|
|
||||||
let mut abs_best = SearchEval::Exact(EVAL_WORST);
|
let mut abs_best = SearchEval::Exact(EVAL_WORST);
|
||||||
|
|
||||||
if mm.quiesce {
|
if mm.quiesce {
|
||||||
|
Loading…
Reference in New Issue
Block a user