diff options
author | eug-vs <eugene@eug-vs.xyz> | 2023-08-16 02:40:17 +0300 |
---|---|---|
committer | eug-vs <eugene@eug-vs.xyz> | 2023-08-16 02:40:17 +0300 |
commit | e2102adf0bc0c7feb5f3e02dbf32655608dca1d7 (patch) | |
tree | f452b1d64ab2385c7868ab03e3b2a5f5747382de | |
parent | 9f8bf52436d3778bbc4f7caf5561f7961c8c1e08 (diff) | |
download | chessnost-e2102adf0bc0c7feb5f3e02dbf32655608dca1d7.tar.gz |
feat: add bonus table for passers
-rw-r--r-- | src/grossmeister/evaluation.rs | 56 |
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); + } } |