use std::sync::atomic::AtomicBool;
use std::sync::Arc;
use std::time::Instant;
use crate::arrayvec::display;
use crate::coretypes::MAX_DEPTH;
use crate::search;
use crate::search::History;
use crate::search::SearchResult;
use crate::timeman::Mode;
use crate::transposition::{Entry, NodeKind, TranspositionTable};
use crate::Position;
pub fn ids(
position: Position,
mode: Mode,
history: History,
tt: &TranspositionTable,
stopper: Arc<AtomicBool>,
debug: bool,
) -> SearchResult {
let hash = tt.generate_hash(&position);
let instant = Instant::now();
let age = position.age();
let mut search_result = SearchResult {
player: position.player,
stopped: true,
..Default::default()
};
for ply in 1..=MAX_DEPTH {
if mode.stop(position.player, ply) {
break;
}
let stopper = Arc::clone(&stopper);
let history = history.clone();
let maybe_result = search::iterative_negamax(position, ply, mode, history, tt, stopper);
if let Some(mut result) = maybe_result {
result.add_metrics(search_result);
search_result = result;
if search_result.stopped {
break;
}
} else {
break;
}
if debug && !search_result.stopped {
println!(
"info depth {} score cp {} time {} nodes {} nps {} pv {}",
search_result.depth,
search_result.relative_score(),
search_result.elapsed.as_millis(),
search_result.nodes,
search_result.nps(),
display(&search_result.pv),
);
}
if search_result.score.is_mate() && !search_result.stopped {
break;
}
let mut position = position.clone();
let mut hash = hash.clone();
let mut move_ply = ply.clone();
let mut relative_pv_score = search_result.relative_score();
for &pv_move in search_result.pv.iter().take(move_ply as usize) {
let pv_entry = Entry::new(hash, pv_move, relative_pv_score, move_ply, NodeKind::Pv);
tt.replace(pv_entry, age);
let cache = position.cache();
let move_info = position.do_move(pv_move);
tt.update_hash(&mut hash, &position, move_info, cache);
move_ply -= 1;
relative_pv_score = -relative_pv_score;
}
}
search_result.elapsed = instant.elapsed();
search_result
}