Return early if king is under check and small refactorings
This commit is contained in:
@@ -6,9 +6,6 @@ use crate::{
|
|||||||
evaluation::psqt::{mirror_index, piece_square_score},
|
evaluation::psqt::{mirror_index, piece_square_score},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const MAX_EVAL: i32 = 100000;
|
|
||||||
pub const MIN_EVAL: i32 = -100000;
|
|
||||||
|
|
||||||
const fn piece_score(piece_type: PieceType) -> i32 {
|
const fn piece_score(piece_type: PieceType) -> i32 {
|
||||||
match piece_type {
|
match piece_type {
|
||||||
PieceType::Pawn => 100,
|
PieceType::Pawn => 100,
|
||||||
|
|||||||
@@ -1,2 +1,6 @@
|
|||||||
pub mod evaluation;
|
pub mod evaluation;
|
||||||
pub mod psqt;
|
pub mod psqt;
|
||||||
|
|
||||||
|
pub const MAX_SCORE: i32 = 100000;
|
||||||
|
pub const MIN_SCORE: i32 = -100000;
|
||||||
|
pub const MATE_SCORE: i32 = 50000;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use std::{
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
board::game::Game,
|
board::game::Game,
|
||||||
evaluation::evaluation::{MAX_EVAL, MIN_EVAL},
|
evaluation::{MAX_SCORE, MIN_SCORE},
|
||||||
movegen::r#move::Move,
|
movegen::r#move::Move,
|
||||||
search,
|
search,
|
||||||
};
|
};
|
||||||
@@ -139,8 +139,8 @@ pub fn uci_go(go: &mut SplitWhitespace, game: &mut Game) -> Result<Move, String>
|
|||||||
}
|
}
|
||||||
Ok(search::negamax::negamax(
|
Ok(search::negamax::negamax(
|
||||||
game,
|
game,
|
||||||
MIN_EVAL,
|
MIN_SCORE,
|
||||||
MAX_EVAL,
|
MAX_SCORE,
|
||||||
params.depth.unwrap_or(MAX_DEPTH),
|
params.depth.unwrap_or(MAX_DEPTH),
|
||||||
0,
|
0,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
board::{game::Game, history::MoveParameters},
|
board::{game::Game, history::MoveParameters},
|
||||||
evaluation::evaluation::evaluate_position,
|
evaluation::{MATE_SCORE, MIN_SCORE},
|
||||||
movegen::r#move::Move,
|
movegen::r#move::Move,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -19,32 +19,32 @@ pub fn negamax(
|
|||||||
return (None, quiescence(game, alpha, beta).1);
|
return (None, quiescence(game, alpha, beta).1);
|
||||||
}
|
}
|
||||||
|
|
||||||
let (mut best_move, mut best_score, mate_score) = (None, -100000, -50000 + plies as i32);
|
let (mut best_move, mut best_score, mate_score) = (None, MIN_SCORE, -MATE_SCORE + plies as i32);
|
||||||
let mut legal_moves = 0;
|
let mut legal_moves = 0;
|
||||||
|
|
||||||
for mv in game.board.pseudo_moves_all(color) {
|
for mv in game.board.pseudo_moves_all(color) {
|
||||||
let move_parameters = MoveParameters::build(&game.board, &mv);
|
let move_parameters = MoveParameters::build(&game.board, &mv);
|
||||||
game.board.make_move(&mv);
|
game.board.make_move(&mv);
|
||||||
|
|
||||||
if !game.board.king_under_check(color) {
|
if game.board.king_under_check(color) {
|
||||||
legal_moves += 1;
|
game.board.unmake_move(move_parameters);
|
||||||
let move_score = -negamax(game, -beta, -alpha, depth - 1, plies + 1).1;
|
continue;
|
||||||
|
|
||||||
if move_score > best_score {
|
|
||||||
best_score = move_score;
|
|
||||||
best_move = Some(mv)
|
|
||||||
}
|
|
||||||
|
|
||||||
if move_score >= beta {
|
|
||||||
game.board.unmake_move(move_parameters);
|
|
||||||
return (Some(mv), beta); // fail hard beta-cutoff
|
|
||||||
}
|
|
||||||
|
|
||||||
if move_score > alpha {
|
|
||||||
alpha = move_score; // alpha acts like max in minimax
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
legal_moves += 1;
|
||||||
|
let move_score = -negamax(game, -beta, -alpha, depth - 1, plies + 1).1;
|
||||||
game.board.unmake_move(move_parameters);
|
game.board.unmake_move(move_parameters);
|
||||||
|
|
||||||
|
if move_score > best_score {
|
||||||
|
best_score = move_score;
|
||||||
|
best_move = Some(mv)
|
||||||
|
}
|
||||||
|
|
||||||
|
if move_score >= beta {
|
||||||
|
return (Some(mv), beta);
|
||||||
|
}
|
||||||
|
|
||||||
|
alpha = alpha.max(move_score);
|
||||||
}
|
}
|
||||||
|
|
||||||
if legal_moves == 0 {
|
if legal_moves == 0 {
|
||||||
@@ -60,7 +60,7 @@ pub fn negamax(
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::board::{fen::from_fen, square::Square};
|
use crate::board::{fen::from_fen, square::Square};
|
||||||
use crate::evaluation::evaluation::{MAX_EVAL, MIN_EVAL};
|
use crate::evaluation::{MAX_SCORE, MIN_SCORE};
|
||||||
use crate::movegen::attack::init_attacks;
|
use crate::movegen::attack::init_attacks;
|
||||||
use crate::movegen::r#move::Move;
|
use crate::movegen::r#move::Move;
|
||||||
use crate::search::negamax::negamax;
|
use crate::search::negamax::negamax;
|
||||||
@@ -73,23 +73,9 @@ mod tests {
|
|||||||
let mut game = from_fen(FEN_MATE_IN_1)?;
|
let mut game = from_fen(FEN_MATE_IN_1)?;
|
||||||
|
|
||||||
let e3f2 = Move::new(Square::E3, Square::F2);
|
let e3f2 = Move::new(Square::E3, Square::F2);
|
||||||
|
let anointed_move = negamax(&mut game, MIN_SCORE, MAX_SCORE, 2, 0).0.unwrap();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(e3f2, anointed_move);
|
||||||
e3f2,
|
|
||||||
negamax(&mut game, MIN_EVAL, MAX_EVAL, 2, 0).0.unwrap()
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
e3f2,
|
|
||||||
negamax(&mut game, MIN_EVAL, MAX_EVAL, 3, 0).0.unwrap()
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
e3f2,
|
|
||||||
negamax(&mut game, MIN_EVAL, MAX_EVAL, 4, 0).0.unwrap()
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
e3f2,
|
|
||||||
negamax(&mut game, MIN_EVAL, MAX_EVAL, 5, 0).0.unwrap()
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user