Fix and simplify move ordering

This commit is contained in:
stefiosif
2025-01-25 16:39:04 +02:00
parent d8cc3b74a2
commit 62c524174e
4 changed files with 35 additions and 42 deletions

View File

@@ -192,17 +192,6 @@ impl PieceType {
pub const fn idx(self) -> usize { pub const fn idx(self) -> usize {
self as 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}; use std::ops::{Index, IndexMut};

View File

@@ -1,22 +1,14 @@
use crate::{board::mailbox::Mailbox, movegen::r#move::Move}; 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> { pub fn score_move(mailbox: &Mailbox, mv: Move, tt_move: Option<Move>) -> i32 {
if let Some(tt_move) = tt_move { if Some(mv) == tt_move {
if let Some(tt_move_index) = moves.iter().position(|&mv| mv == tt_move) { return -100;
moves.swap_remove(tt_move_index);
moves.insert(0, tt_move);
return moves;
}
} }
moves.sort_unstable_by_key(|mv| std::cmp::Reverse(mvv_lva(mailbox, *mv))); let aggressor = mailbox.piece_at(mv.src).expect("No aggressor found.");
moves match mailbox.piece_at(mv.dst) {
} Some(victim) => aggressor.0.idx() as i32 - (victim.0.idx() * 8) as i32,
None => 100,
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,
} }
} }
@@ -25,17 +17,28 @@ mod tests {
use crate::{ use crate::{
board::{fen::from_fen, square::Square}, board::{fen::from_fen, square::Square},
movegen::r#move::{Move, MoveType}, 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] #[test]
fn test_score_by_mvv_lva() -> Result<(), String> { fn test_score_move() -> Result<(), String> {
let game = from_fen(FEN)?; 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(()) Ok(())
} }

View File

@@ -6,7 +6,7 @@ use crate::{
}; };
use super::{ use super::{
move_ordering, move_ordering::score_move,
quiescence::quiescence, quiescence::quiescence,
time::{hard_limit, TimeInfo}, time::{hard_limit, TimeInfo},
transposition_table::TTEntry, transposition_table::TTEntry,
@@ -33,14 +33,14 @@ pub fn negamax(
return Ok(q_score); 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 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 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 { for mv in moves {
game.make_move(&mv); game.make_move(&mv);

View File

@@ -3,7 +3,7 @@ use anyhow::{bail, Result};
use crate::{board::game::Game, evaluation::pesto::pesto}; use crate::{board::game::Game, evaluation::pesto::pesto};
use super::{ use super::{
move_ordering, move_ordering::score_move,
time::{hard_limit, TimeInfo}, 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 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 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 { for mv in moves {
game.make_move(&mv); game.make_move(&mv);