Add Null-move pruning

This commit is contained in:
stefiosif
2025-01-29 23:09:01 +02:00
parent 91ad3de8b1
commit 888b3866b9
7 changed files with 125 additions and 12 deletions

View File

@@ -20,6 +20,7 @@ pub fn negamax(
plies: u8,
time: &TimeInfo,
nodes: &mut u64,
do_nmp: bool,
) -> Result<i32> {
if time.exceed_hard_limit() {
bail!("Hard limit exceeded in negamax");
@@ -41,6 +42,25 @@ pub fn negamax(
return Ok(q_score);
}
if plies != 0 && !in_check && depth >= 3 && do_nmp && game.board.non_pawn_materials() > 0 {
game.make_null_move();
let score = -negamax(
game,
-beta,
-beta + 1,
depth - 3,
plies + 1,
time,
nodes,
false,
)?;
game.unmake_null_move();
if score >= beta {
return Ok(score);
}
}
let mut legal_moves = 0;
let mut best_score = MIN_SCORE;
let mut best_move = None;
@@ -78,11 +98,20 @@ pub fn negamax(
*nodes += 1;
let score = if legal_moves == 1 {
-negamax(game, -beta, -alpha, depth - 1, plies + 1, time, nodes)?
-negamax(game, -beta, -alpha, depth - 1, plies + 1, time, nodes, true)?
} else {
let mut score = -negamax(game, -alpha - 1, -alpha, depth - 1, plies + 1, time, nodes)?;
let mut score = -negamax(
game,
-alpha - 1,
-alpha,
depth - 1,
plies + 1,
time,
nodes,
true,
)?;
if score > alpha && score < beta {
score = -negamax(game, -beta, -alpha, depth - 1, plies + 1, time, nodes)?;
score = -negamax(game, -beta, -alpha, depth - 1, plies + 1, time, nodes, true)?;
}
score
};
@@ -147,16 +176,20 @@ mod tests {
let e3f2 = Move::new(Square::E3, Square::F2);
let time_info = TimeInfo::new(std::time::Instant::now(), TIME, INC);
negamax(&mut game, MIN_SCORE, MAX_SCORE, 2, 0, &time_info, &mut 0)
.expect("Expected a search result");
negamax(
&mut game, MIN_SCORE, MAX_SCORE, 5, 0, &time_info, &mut 0, true,
)
.expect("Expected a search result");
assert_eq!(e3f2, game.tt.lookup(game.hash).unwrap().mv.unwrap());
let mut game = from_fen(FEN_MATE_IN_1[1]).unwrap();
let e3f2 = Move::new(Square::E3, Square::F2);
negamax(&mut game, MIN_SCORE, MAX_SCORE, 2, 0, &time_info, &mut 0)
.expect("Expected a search result");
negamax(
&mut game, MIN_SCORE, MAX_SCORE, 5, 0, &time_info, &mut 0, true,
)
.expect("Expected a search result");
assert_eq!(e3f2, game.tt.lookup(game.hash).unwrap().mv.unwrap());