aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoreug-vs <eugene@eug-vs.xyz>2023-08-16 02:40:17 +0300
committereug-vs <eugene@eug-vs.xyz>2023-08-16 02:40:17 +0300
commite2102adf0bc0c7feb5f3e02dbf32655608dca1d7 (patch)
treef452b1d64ab2385c7868ab03e3b2a5f5747382de
parent9f8bf52436d3778bbc4f7caf5561f7961c8c1e08 (diff)
downloadchessnost-e2102adf0bc0c7feb5f3e02dbf32655608dca1d7.tar.gz
feat: add bonus table for passers
-rw-r--r--src/grossmeister/evaluation.rs56
1 files changed, 55 insertions, 1 deletions
diff --git a/src/grossmeister/evaluation.rs b/src/grossmeister/evaluation.rs
index eb59b92..572fa63 100644
--- a/src/grossmeister/evaluation.rs
+++ b/src/grossmeister/evaluation.rs
@@ -16,6 +16,18 @@ const PAWN_BONUS: [f32; 64] = [
0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00
];
+const PAWN_PASSER_BONUS: [f32; 64] = [
+ // A B C D E F G H
+ 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00,
+ 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00, 2.00,
+ 1.50, 1.50, 1.50, 1.50, 1.50, 1.50, 1.50, 1.50,
+ 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00,
+ 0.70, 0.70, 0.70, 0.70, 0.70, 0.70, 0.70, 0.70,
+ 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50,
+ 0.20, 0.20, 0.20, 0.20, 0.20, 0.20, 0.20, 0.20,
+ 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00,
+];
+
const KNIGHT_BONUS: [f32; 64] = [
// A B C D E F G H
-0.50, -0.40, -0.30, -0.30, -0.30, -0.30, -0.40, -0.50,
@@ -94,6 +106,25 @@ impl Grossmeister {
self.board.piece_sets[Piece::Queen as usize].pop_count() == 0 &&
self.board.piece_sets[Piece::QueenBlack as usize].pop_count() == 0
}
+
+ pub fn passer_mask(&self, color: Color) -> Bitboard {
+ let black_pawns = self.board.piece_sets[Piece::PawnBlack as usize];
+ let white_pawns = self.board.piece_sets[Piece::Pawn as usize];
+
+ match color {
+ Color::Black => {
+ let mut front_fill = white_pawns.nort_fill().nort_one();
+ front_fill |= front_fill.east_one() | front_fill.west_one();
+ black_pawns & !front_fill
+ }
+ Color::White => {
+ let mut front_fill = black_pawns.sout_fill().sout_one();
+ front_fill |= front_fill.east_one() | front_fill.west_one();
+ white_pawns & !front_fill
+ }
+ }
+ }
+
/// Evaluate a position relative to the current player
pub fn evaluate(&self) -> f32 {
let color = self.board.color();
@@ -117,12 +148,18 @@ impl Grossmeister {
/// Count player pieces' material, giving bonus for pieces standing well
pub fn material(&self, color: Color) -> f32 {
let is_endgame = self.is_endgame();
+ let passer_mask = self.passer_mask(color);
+
let mut material = 0f32;
for (piece_index, bitboard) in self.board.pieces_by_color(color).iter().enumerate() {
let piece_type = Piece::from(piece_index);
let bonus_table = match piece_type {
- Piece::Pawn => PAWN_BONUS,
+ Piece::Pawn => if bitboard & passer_mask != 0 {
+ PAWN_PASSER_BONUS
+ } else {
+ PAWN_BONUS
+ }
Piece::Knight => KNIGHT_BONUS,
Piece::Bishop => BISHOP_BONUS,
Piece::Rook => ROOK_BONUS,
@@ -510,4 +547,21 @@ mod tests {
let is_endgame = gm.is_endgame();
assert!(is_endgame);
}
+
+ #[test]
+ fn passer() {
+ let fen = String::from("rnbqkbnr/ppp3pp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1");
+ let board = Board::from_FEN(fen);
+ let gm = Grossmeister::new(board);
+ let mask = gm.passer_mask(Color::White);
+ assert_eq!(mask, Square::E2.to_bitboard());
+ }
+
+ #[test]
+ fn no_passer() {
+ let board = Board::new();
+ let gm = Grossmeister::new(board);
+ let mask = gm.passer_mask(Color::White);
+ assert_eq!(mask, 0);
+ }
}