Fix and simplify move ordering
This commit is contained in:
@@ -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};
|
||||||
|
|
||||||
|
|||||||
@@ -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(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user