diff options
Diffstat (limited to 'src/grossmeister/evaluation.rs')
-rw-r--r-- | src/grossmeister/evaluation.rs | 44 |
1 files changed, 12 insertions, 32 deletions
diff --git a/src/grossmeister/evaluation.rs b/src/grossmeister/evaluation.rs index b78c49a..6fc4149 100644 --- a/src/grossmeister/evaluation.rs +++ b/src/grossmeister/evaluation.rs @@ -1,3 +1,5 @@ +use std::f32::INFINITY; + use crate::{board::{piece::Piece, color::Color, CastlingSide}, bitboard::{Bitboard, BitboardFns}, square::Square}; use super::Grossmeister; @@ -117,34 +119,6 @@ impl Grossmeister { } } - pub fn is_dead_position(&self) -> bool { - let non_minor_exists = [ - Piece::Pawn, - Piece::PawnBlack, - Piece::Rook, - Piece::RookBlack, - Piece::Queen, - Piece::QueenBlack - ].iter().any(|&piece| { - self.board.piece_sets[piece as usize].pop_count() > 0 - }); - - if non_minor_exists { - return false; - } - - let minor_pieces = [ - Piece::Knight, - Piece::KnightBlack, - Piece::Bishop, - Piece::BishopBlack - ].iter().fold(0, |acc, &piece| { - acc + self.board.piece_sets[piece as usize].pop_count() - }); - - minor_pieces <= 1 - } - /// Return number of pawns above the king (+left/right) pub fn pawn_shield(&self, color: Color) -> f32 { let behind_pawns = match color { @@ -236,12 +210,16 @@ impl Grossmeister { /// Evaluate a position relative to the current player pub fn evaluate(&self) -> f32 { - if self.is_dead_position() { - return 0.0 - } let color = self.board.color(); let opponent_color = color.flip(); + let winnable = self.board.is_theoretically_winnable(color); + let loseable = self.board.is_theoretically_winnable(opponent_color); + + if !winnable && !loseable { + return 0.0 + } + let material_advantage = self.material(color) - self.material(opponent_color); let mobility_advantage = self.mobility(color) - self.mobility(opponent_color); let pawn_shield_advantage = self.pawn_shield(color) - self.pawn_shield(opponent_color); @@ -265,7 +243,9 @@ impl Grossmeister { let phase = self.phase(); let tapered_eval = (middlegame_eval * phase as f32 + endgame_eval * (240 - phase) as f32) / 240.; - material_advantage + tapered_eval + (material_advantage + tapered_eval) + .min(if winnable { INFINITY } else { 0.0 }) // Can not score > 0 if not winnable + .max(if loseable { -INFINITY } else { 0.0 }) // Can not score < 0 if not loseable } /// Count pseudo-legal moves without actually generating them |