67 lines
1.5 KiB
Rust
67 lines
1.5 KiB
Rust
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<Option<Move>> {
|
|
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(())
|
|
}
|
|
}
|