aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoreug-vs <eugene@eug-vs.xyz>2023-01-27 21:37:15 +0300
committereug-vs <eugene@eug-vs.xyz>2023-01-27 21:40:34 +0300
commit345781ddc28b3f5987beb5b21acda6e532e0a37a (patch)
tree13ce562697d5c4197a8f285c6e6345ca2c4e5120
parenta85b31683d782c2cbcfc97e06f1cfb53ac9aee0a (diff)
downloadchessnost-345781ddc28b3f5987beb5b21acda6e532e0a37a.tar.gz
feat: prioritize equal captures over non-captures
-rw-r--r--src/board/engine.rs37
-rw-r--r--src/moves.rs9
2 files changed, 31 insertions, 15 deletions
diff --git a/src/board/engine.rs b/src/board/engine.rs
index 47890ad..05cb1e7 100644
--- a/src/board/engine.rs
+++ b/src/board/engine.rs
@@ -1,4 +1,4 @@
-use std::{time::{Instant, Duration}, f32::INFINITY};
+use std::{time::{Instant, Duration}, f32::INFINITY, cmp::Ordering};
use crate::{bitboard::pop_count, board::*};
use super::ttable::{NodeType, TranspositionTableItem};
@@ -173,7 +173,7 @@ impl Board {
/// Evaluate move for move ordering, prioritizing efficient captures
/// where low-value pieces capture high-value pieces
fn eval_move(&self, m: Move) -> f32 {
- if m.kind == MoveKind::Capture || m.kind == MoveKind::EnPassant {
+ if m.is_tactical() {
let [source_eval, target_eval] = [m.source, m.target]
.map(|sq| self.piece_by_square(sq))
.map(|p| {
@@ -187,17 +187,29 @@ impl Board {
0.0
}
- pub fn negamax_search(&mut self, mut alpha: f32, beta: f32, depth_left: u8, deadline: Instant) -> (f32, Vec<Move>) {
- let mut principal_variation = Vec::new();
- let color = self.color();
-
- let mut moves = self.generate_pseudolegal_moves(color);
-
+ pub fn order_moves(&self, moves: &mut Vec<Move>) {
moves.sort_unstable_by(|a, b| {
let a_eval = self.eval_move(*a);
let b_eval = self.eval_move(*b);
+ if a_eval == 0.0 && b_eval == 0.0 {
+ // Prioritize equal captures over non-captures
+ if a.is_tactical() && !b.is_tactical() {
+ return Ordering::Less
+ }
+ if b.is_tactical() && !a.is_tactical() {
+ return Ordering::Greater
+ }
+ }
a_eval.total_cmp(&b_eval).reverse()
});
+ }
+
+ pub fn negamax_search(&mut self, mut alpha: f32, beta: f32, depth_left: u8, deadline: Instant) -> (f32, Vec<Move>) {
+ let mut principal_variation = Vec::new();
+ let color = self.color();
+
+ let mut moves = self.generate_pseudolegal_moves(color);
+ self.order_moves(&mut moves);
match self.transposition_table[(self.hash % TTABLE_SIZE) as usize] {
Some(item) => {
@@ -273,12 +285,7 @@ impl Board {
pub fn quiscence(&mut self, mut alpha: f32, beta: f32) -> f32 {
let color = self.color();
let mut moves = self.generate_pseudolegal_moves(color);
-
- moves.sort_unstable_by(|a, b| {
- let a_eval = self.eval_move(*a);
- let b_eval = self.eval_move(*b);
- a_eval.total_cmp(&b_eval).reverse()
- });
+ self.order_moves(&mut moves);
match self.transposition_table[(self.hash % TTABLE_SIZE) as usize] {
Some(item) => {
@@ -298,7 +305,7 @@ impl Board {
alpha = stand_pat;
}
- let tactical_moves = moves.iter().filter(|m| m.kind == MoveKind::Capture || m.kind == MoveKind::EnPassant);
+ let tactical_moves = moves.iter().filter(|m| m.is_tactical());
for mov in tactical_moves {
let ep_target_before = self.ep_target.clone();
diff --git a/src/moves.rs b/src/moves.rs
index 87b7c4b..34f8370 100644
--- a/src/moves.rs
+++ b/src/moves.rs
@@ -22,6 +22,15 @@ impl Move {
let bb = self.source.to_bitboard() | self.target.to_bitboard();
print(bb, format!("{:?}", self).as_str());
}
+
+ /// Tactical move is a move that changes material score
+ pub fn is_tactical(&self) -> bool {
+ match self.kind {
+ MoveKind::Capture => true,
+ MoveKind::EnPassant => true,
+ _ => false,
+ }
+ }
}