Fix and simplify move ordering
This commit is contained in:
@@ -192,17 +192,6 @@ impl PieceType {
|
||||
pub const fn idx(self) -> usize {
|
||||
self as usize
|
||||
}
|
||||
|
||||
pub const fn score(self) -> i32 {
|
||||
match self {
|
||||
Self::Pawn => 100,
|
||||
Self::Knight => 320,
|
||||
Self::Bishop => 330,
|
||||
Self::Rook => 500,
|
||||
Self::Queen => 900,
|
||||
Self::King => 20000,
|
||||
}
|
||||
}
|
||||
}
|
||||
use std::ops::{Index, IndexMut};
|
||||
|
||||
|
||||
@@ -1,22 +1,14 @@
|
||||
use crate::{board::mailbox::Mailbox, movegen::r#move::Move};
|
||||
|
||||
pub fn sort_moves(mut moves: Vec<Move>, mailbox: &Mailbox, tt_move: Option<Move>) -> Vec<Move> {
|
||||
if let Some(tt_move) = tt_move {
|
||||
if let Some(tt_move_index) = moves.iter().position(|&mv| mv == tt_move) {
|
||||
moves.swap_remove(tt_move_index);
|
||||
moves.insert(0, tt_move);
|
||||
return moves;
|
||||
}
|
||||
pub fn score_move(mailbox: &Mailbox, mv: Move, tt_move: Option<Move>) -> i32 {
|
||||
if Some(mv) == tt_move {
|
||||
return -100;
|
||||
}
|
||||
|
||||
moves.sort_unstable_by_key(|mv| std::cmp::Reverse(mvv_lva(mailbox, *mv)));
|
||||
moves
|
||||
}
|
||||
|
||||
const fn mvv_lva(mailbox: &Mailbox, mv: Move) -> i32 {
|
||||
match (mailbox.piece_at(mv.src), mailbox.piece_at(mv.dst)) {
|
||||
(Some(aggressor), Some(victim)) => victim.0.score() - aggressor.0.score(),
|
||||
_ => -1000,
|
||||
let aggressor = mailbox.piece_at(mv.src).expect("No aggressor found.");
|
||||
match mailbox.piece_at(mv.dst) {
|
||||
Some(victim) => aggressor.0.idx() as i32 - (victim.0.idx() * 8) as i32,
|
||||
None => 100,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,17 +17,28 @@ mod tests {
|
||||
use crate::{
|
||||
board::{fen::from_fen, square::Square},
|
||||
movegen::r#move::{Move, MoveType},
|
||||
search::move_ordering::mvv_lva,
|
||||
};
|
||||
|
||||
const FEN: &'static str = "1r2k2r/2P1pq1p/2npb3/1p3ppP/p3P3/P2B1Q2/1P1PNPP1/R3K2R w KQk g6 0 1";
|
||||
use super::score_move;
|
||||
|
||||
const FEN: &'static str = "1r2k2r/2P1p2p/2npb1q1/1p3ppP/p3P3/P2B1Q2/1P1PNPP1/R3K2R w KQk - 0 1";
|
||||
|
||||
#[test]
|
||||
fn test_score_by_mvv_lva() -> Result<(), String> {
|
||||
fn test_score_move() -> Result<(), String> {
|
||||
let game = from_fen(FEN)?;
|
||||
let f3f5 = Move::with_type(Square::F3, Square::F5, MoveType::Capture);
|
||||
let queen_takes_pawn = Move::with_type(Square::F3, Square::F5, MoveType::Capture);
|
||||
let pawn_takes_queen = Move::with_type(Square::H5, Square::G6, MoveType::Capture);
|
||||
let castle = Move::with_type(Square::E1, Square::C1, MoveType::Castle);
|
||||
|
||||
assert_eq!(mvv_lva(&game.mailbox, f3f5), -800);
|
||||
let mut moves = vec![castle, queen_takes_pawn, pawn_takes_queen];
|
||||
moves.sort_unstable_by_key(|mv| score_move(&game.mailbox, *mv, None));
|
||||
|
||||
assert_eq!(moves, vec![pawn_takes_queen, queen_takes_pawn, castle]);
|
||||
|
||||
let castle = Move::with_type(Square::E1, Square::C1, MoveType::Castle);
|
||||
moves.sort_unstable_by_key(|mv| score_move(&game.mailbox, *mv, Some(castle)));
|
||||
|
||||
assert_eq!(moves, vec![castle, pawn_takes_queen, queen_takes_pawn]);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ use crate::{
|
||||
};
|
||||
|
||||
use super::{
|
||||
move_ordering,
|
||||
move_ordering::score_move,
|
||||
quiescence::quiescence,
|
||||
time::{hard_limit, TimeInfo},
|
||||
transposition_table::TTEntry,
|
||||
@@ -33,14 +33,14 @@ pub fn negamax(
|
||||
return Ok(q_score);
|
||||
}
|
||||
|
||||
let color = game.current_player();
|
||||
let mut best_move = None;
|
||||
let mut best_score = MIN_SCORE;
|
||||
let mut legal_moves = 0;
|
||||
let all_moves = game.board.pseudo_moves_all();
|
||||
|
||||
let color = game.current_player();
|
||||
let mut best_score = MIN_SCORE;
|
||||
let mut best_move = None;
|
||||
let mut moves = game.board.pseudo_moves_all();
|
||||
let tt_move = game.tt.lookup(game.hash).and_then(|entry| entry.mv);
|
||||
let moves = move_ordering::sort_moves(all_moves, &game.mailbox, tt_move);
|
||||
|
||||
moves.sort_unstable_by_key(|mv| score_move(&game.mailbox, *mv, tt_move));
|
||||
|
||||
for mv in moves {
|
||||
game.make_move(&mv);
|
||||
|
||||
@@ -3,7 +3,7 @@ use anyhow::{bail, Result};
|
||||
use crate::{board::game::Game, evaluation::pesto::pesto};
|
||||
|
||||
use super::{
|
||||
move_ordering,
|
||||
move_ordering::score_move,
|
||||
time::{hard_limit, TimeInfo},
|
||||
};
|
||||
|
||||
@@ -23,10 +23,11 @@ pub fn quiescence(game: &mut Game, mut alpha: i32, beta: i32, time_info: &TimeIn
|
||||
}
|
||||
|
||||
let color = game.current_player();
|
||||
let all_moves = game.board.pseudo_moves_all_captures();
|
||||
let tt_move = game.tt.lookup(game.hash).and_then(|entry| entry.mv);
|
||||
let moves = move_ordering::sort_moves(all_moves, &game.mailbox, tt_move);
|
||||
let mut best_score = stand_pat;
|
||||
let mut moves = game.board.pseudo_moves_all_captures();
|
||||
let tt_move = game.tt.lookup(game.hash).and_then(|entry| entry.mv);
|
||||
|
||||
moves.sort_unstable_by_key(|mv| score_move(&game.mailbox, *mv, tt_move));
|
||||
|
||||
for mv in moves {
|
||||
game.make_move(&mv);
|
||||
|
||||
Reference in New Issue
Block a user