97 lines
2.2 KiB
Rust
97 lines
2.2 KiB
Rust
use std::io;
|
|
|
|
use crate::{
|
|
board::game::Game,
|
|
evaluation::{MAX_SCORE, MIN_SCORE},
|
|
interface::uci::{write_response, Response},
|
|
movegen::r#move::Move,
|
|
};
|
|
|
|
use super::{
|
|
negamax,
|
|
time::{hard_limit, TimeInfo},
|
|
};
|
|
|
|
pub fn iterative_deepening(
|
|
game: &mut Game,
|
|
max_depth: u8,
|
|
time_info: &TimeInfo,
|
|
) -> anyhow::Result<Option<Move>> {
|
|
let mut best_move = None;
|
|
|
|
for depth in 1..=max_depth {
|
|
if hard_limit(time_info.instant, time_info.time, time_info.inc) {
|
|
return Ok(best_move);
|
|
}
|
|
|
|
let mut nodes = 0;
|
|
let score = negamax::negamax(game, MIN_SCORE, MAX_SCORE, depth, 0, time_info, &mut nodes);
|
|
|
|
if score.is_err() {
|
|
break;
|
|
}
|
|
|
|
best_move = game.tt.lookup(game.hash).and_then(|entry| entry.mv);
|
|
|
|
write_response(
|
|
&mut io::stdout(),
|
|
&log_depth_results(
|
|
depth,
|
|
time_info.instant.elapsed().as_millis() as u64,
|
|
nodes,
|
|
time_info.nps(nodes),
|
|
score?,
|
|
best_move,
|
|
),
|
|
)?;
|
|
}
|
|
Ok(best_move)
|
|
}
|
|
|
|
fn log_depth_results(
|
|
depth: u8,
|
|
seconds: u64,
|
|
nodes: u64,
|
|
nps: u64,
|
|
best_score: i32,
|
|
best_move: Option<Move>,
|
|
) -> Response {
|
|
Response::Info(format!(
|
|
"info depth {} seconds {} nodes {} nps {} eval {} bestmove {}",
|
|
depth,
|
|
seconds,
|
|
nodes,
|
|
nps,
|
|
best_score,
|
|
best_move.expect("No best move found")
|
|
))
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use crate::{
|
|
board::fen::from_fen,
|
|
movegen::attack_generator::init_attacks,
|
|
search::{iterative_deepening, time::TimeInfo, INC, MAX_DEPTH, TIME},
|
|
};
|
|
|
|
const FEN: &str = "1r2k2r/2P1pq1p/2npb3/1p3ppP/p3P3/P2B1Q2/1P1PNPP1/R3K2R w KQk g6 0 1";
|
|
|
|
#[test]
|
|
fn test_iterative_deepening() -> anyhow::Result<()> {
|
|
init_attacks();
|
|
let mut game = from_fen(FEN).unwrap();
|
|
let instant = std::time::Instant::now();
|
|
|
|
iterative_deepening::iterative_deepening(
|
|
&mut game,
|
|
MAX_DEPTH,
|
|
&TimeInfo::new(instant, TIME, INC),
|
|
)?;
|
|
|
|
dbg!(instant.elapsed());
|
|
|
|
Ok(())
|
|
}
|
|
}
|