diff --git a/src/search/mod.rs b/src/search/mod.rs index 957be4a..8d9dbe4 100644 --- a/src/search/mod.rs +++ b/src/search/mod.rs @@ -1,2 +1,3 @@ pub mod negamax; pub mod perft; +pub mod quiescence; diff --git a/src/search/negamax.rs b/src/search/negamax.rs index b34f735..024705c 100644 --- a/src/search/negamax.rs +++ b/src/search/negamax.rs @@ -4,6 +4,8 @@ use crate::{ movegen::r#move::Move, }; +use super::quiescence::quiescence; + pub fn negamax( game: &mut Game, mut alpha: i32, @@ -14,7 +16,7 @@ pub fn negamax( let color = game.current_player(); if depth == 0 { - return (None, evaluate_position(&game.board)); + return (None, quiescence(game, alpha, beta).1); } let (mut best_move, mut best_score, mate_score) = (None, -100000, -50000 + plies as i32); diff --git a/src/search/quiescence.rs b/src/search/quiescence.rs new file mode 100644 index 0000000..b8820ce --- /dev/null +++ b/src/search/quiescence.rs @@ -0,0 +1,45 @@ +use crate::{ + board::{game::Game, history::MoveParameters}, + evaluation::evaluation::evaluate_position, + movegen::r#move::{Move, MoveType}, +}; + +pub fn quiescence(game: &mut Game, mut alpha: i32, beta: i32) -> (Option, i32) { + let color = game.current_player(); + let stand_pat = evaluate_position(&game.board); + + if stand_pat >= beta { + return (None, beta); + } + + if alpha < stand_pat { + alpha = stand_pat; + } + + let captures = game + .board + .pseudo_moves_all(color) + .into_iter() + .filter(|m| !matches!(m.move_type, MoveType::Quiet)); + + for mv in captures { + let move_parameters = MoveParameters::build(&game.board, &mv); + game.board.make_move(&mv); + + if game.board.king_under_check(color) { + game.board.unmake_move(move_parameters); + continue; + } + + let move_score = -quiescence(game, -beta, -alpha).1; + game.board.unmake_move(move_parameters); + + if move_score >= beta { + return (Some(mv), beta); + } + + alpha = alpha.max(move_score); + } + + (None, 0) +}