use crate::{ board::game::Game, evaluation::{MAX_SCORE, MIN_SCORE}, movegen::r#move::Move, }; use super::{ negamax, time::{soft_limit, TimeInfo}, }; pub fn iterative_deepening( game: &mut Game, max_depth: u8, remaining_time: u128, ) -> anyhow::Result> { let (mut best_move, mut best_score) = (None, MIN_SCORE); let time = std::time::Instant::now(); for depth in 1..=max_depth { if soft_limit(&time, remaining_time, best_score) { return Ok(best_move); } let score = negamax::negamax( game, MIN_SCORE, MAX_SCORE, depth, 0, &TimeInfo::new(time, remaining_time), ); if score.is_err() { break; } best_score = score?; best_move = game.tt.lookup(game.hash).and_then(|entry| entry.mv); } Ok(best_move) } #[cfg(test)] mod tests { use crate::{ board::fen::from_fen, movegen::attack_generator::init_attacks, search::{iterative_deepening, MAX_DEPTH, REMAINING_TIME_DEFAULT}, }; 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 time_now = std::time::Instant::now(); iterative_deepening::iterative_deepening(&mut game, MAX_DEPTH, REMAINING_TIME_DEFAULT)?; dbg!(time_now.elapsed()); Ok(()) } }