diff --git a/CHANGELOG.md b/CHANGELOG.md index a9f7aa1..2e2d6f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ * Tune all evaluation parameters with https://github.com/GediminasMasaitis/texel-tuner (53.17 +- 16.76) * Evaluate piece mobility (41.36 +- 13.82) * Add a texel tuner in-repo and tune, resolving an issue where mobility scores were not computed correctly (28.53 +- 11.44) +* Evaluate king safety (24.27 +- 10.43) ### Misc diff --git a/src/engine/eval/mobility.rs b/src/engine/eval/mobility.rs deleted file mode 100644 index 1bec3c5..0000000 --- a/src/engine/eval/mobility.rs +++ /dev/null @@ -1,39 +0,0 @@ -use super::PhasedEval; -use crate::chess::game::Game; -use crate::chess::movegen::tables; -use crate::chess::player::Player; -use crate::engine::eval::params::{ - BISHOP_MOBILITY, KNIGHT_MOBILITY, QUEEN_MOBILITY, ROOK_MOBILITY, -}; - -fn mobility_for(game: &Game, player: Player) -> PhasedEval { - let mut eval = PhasedEval::ZERO; - let blockers = game.board.occupancy(); - - for p in game.board.knights(player) { - let moves = tables::knight_attacks(p).count() as usize; - eval += KNIGHT_MOBILITY[moves]; - } - - for p in game.board.bishops(player) { - let moves = tables::bishop_attacks(p, blockers).count() as usize; - eval += BISHOP_MOBILITY[moves]; - } - - for p in game.board.rooks(player) { - let moves = tables::rook_attacks(p, blockers).count() as usize; - eval += ROOK_MOBILITY[moves]; - } - - for p in game.board.queens(player) { - let moves = (tables::bishop_attacks(p, blockers) | tables::rook_attacks(p, blockers)) - .count() as usize; - eval += QUEEN_MOBILITY[moves]; - } - - eval -} - -pub fn eval(game: &Game) -> PhasedEval { - mobility_for(game, Player::White) - mobility_for(game, Player::Black) -} diff --git a/src/engine/eval/mobility_and_king_safety.rs b/src/engine/eval/mobility_and_king_safety.rs new file mode 100644 index 0000000..803c5f6 --- /dev/null +++ b/src/engine/eval/mobility_and_king_safety.rs @@ -0,0 +1,52 @@ +use super::PhasedEval; +use crate::chess::bitboard::Bitboard; +use crate::chess::game::Game; +use crate::chess::movegen::tables; +use crate::chess::player::Player; +use crate::engine::eval::params::{ + ATTACKED_KING_SQUARES, BISHOP_MOBILITY, KNIGHT_MOBILITY, QUEEN_MOBILITY, ROOK_MOBILITY, +}; + +fn mobility_and_opp_king_safety_for(game: &Game, player: Player) -> PhasedEval { + let mut eval = PhasedEval::ZERO; + let blockers = game.board.occupancy(); + + let mut attacked_squares = Bitboard::EMPTY; + + for p in game.board.knights(player) { + let moves = tables::knight_attacks(p); + attacked_squares |= moves; + eval += KNIGHT_MOBILITY[moves.count() as usize]; + } + + for p in game.board.bishops(player) { + let moves = tables::bishop_attacks(p, blockers); + attacked_squares |= moves; + eval += BISHOP_MOBILITY[moves.count() as usize]; + } + + for p in game.board.rooks(player) { + let moves = tables::rook_attacks(p, blockers); + attacked_squares |= moves; + eval += ROOK_MOBILITY[moves.count() as usize]; + } + + for p in game.board.queens(player) { + let moves = tables::bishop_attacks(p, blockers) | tables::rook_attacks(p, blockers); + attacked_squares |= moves; + eval += QUEEN_MOBILITY[moves.count() as usize]; + } + + let enemy_king = game.board.king(player.other()).single(); + let enemy_king_surrounding_squares = tables::king_attacks(enemy_king); + let attacks_on_enemy_king = attacked_squares & enemy_king_surrounding_squares; + + eval -= ATTACKED_KING_SQUARES[attacks_on_enemy_king.count() as usize]; + + eval +} + +pub fn eval(game: &Game) -> PhasedEval { + mobility_and_opp_king_safety_for(game, Player::White) + - mobility_and_opp_king_safety_for(game, Player::Black) +} diff --git a/src/engine/eval/mod.rs b/src/engine/eval/mod.rs index c1f7c81..a7b24d4 100644 --- a/src/engine/eval/mod.rs +++ b/src/engine/eval/mod.rs @@ -1,5 +1,5 @@ mod material; -mod mobility; +mod mobility_and_king_safety; mod params; mod phased_eval; pub mod piece_square_tables; @@ -60,7 +60,7 @@ pub fn eval(game: &Game) -> Eval { pub fn absolute_eval(game: &Game) -> WhiteEval { let eval = game.incremental_eval.piece_square_tables + material::eval(game) - + mobility::eval(game); + + mobility_and_king_safety::eval(game); eval.for_phase(game.incremental_eval.phase_value) } diff --git a/src/engine/eval/params.rs b/src/engine/eval/params.rs index 5e9ac50..f746735 100644 --- a/src/engine/eval/params.rs +++ b/src/engine/eval/params.rs @@ -10,156 +10,168 @@ pub const fn s(mg: i16, eg: i16) -> PhasedEval { pub type PieceSquareTableDefinition = [[PhasedEval; File::N]; Rank::N]; pub const PIECE_VALUES: [PhasedEval; 6] = [ - s( 113, 225), - s( 269, 306), - s( 285, 339), - s( 376, 591), - s( 771, 1125), + s( 115, 223), + s( 268, 309), + s( 282, 341), + s( 371, 592), + s( 763, 1129), s( 0, 0), ]; pub const PAWNS: PieceSquareTableDefinition = [ [s( 0, 0), s( 0, 0), s( 0, 0), s( 0, 0), s( 0, 0), s( 0, 0), s( 0, 0), s( 0, 0)], - [s( 56, 187), s( 98, 175), s( 64, 177), s( 99, 107), s( 80, 101), s( 58, 120), s( -34, 182), s( -72, 200)], - [s( -36, 98), s( -13, 111), s( 26, 65), s( 31, 35), s( 36, 21), s( 67, 2), s( 47, 66), s( -14, 61)], - [s( -50, -3), s( -15, -17), s( -15, -43), s( -9, -56), s( 17, -69), s( 4, -64), s( 14, -38), s( -19, -38)], - [s( -61, -38), s( -23, -41), s( -21, -67), s( -1, -70), s( 4, -74), s( -5, -73), s( -3, -55), s( -33, -65)], - [s( -57, -48), s( -28, -44), s( -24, -69), s( -16, -54), s( 3, -63), s( -10, -68), s( 20, -58), s( -19, -72)], - [s( -53, -43), s( -23, -39), s( -32, -59), s( -24, -43), s( -10, -41), s( 10, -60), s( 35, -59), s( -30, -71)], + [s( 63, 186), s( 103, 174), s( 72, 176), s( 107, 107), s( 87, 101), s( 67, 119), s( -26, 181), s( -69, 200)], + [s( -34, 99), s( -11, 112), s( 29, 65), s( 33, 36), s( 40, 22), s( 71, 3), s( 49, 67), s( -14, 62)], + [s( -50, -2), s( -15, -16), s( -15, -42), s( -9, -55), s( 17, -68), s( 4, -63), s( 12, -37), s( -22, -36)], + [s( -61, -37), s( -23, -40), s( -21, -66), s( -2, -69), s( 3, -73), s( -7, -72), s( -5, -53), s( -37, -64)], + [s( -58, -47), s( -28, -43), s( -25, -67), s( -18, -53), s( 1, -61), s( -13, -67), s( 16, -57), s( -23, -70)], + [s( -54, -42), s( -24, -38), s( -33, -58), s( -26, -41), s( -12, -40), s( 7, -60), s( 31, -58), s( -34, -69)], [s( 0, 0), s( 0, 0), s( 0, 0), s( 0, 0), s( 0, 0), s( 0, 0), s( 0, 0), s( 0, 0)], ]; pub const KNIGHTS: PieceSquareTableDefinition = [ - [s( -113, -61), s( -140, 7), s( -79, -14), s( -31, -25), s( 18, -21), s( -60, -56), s( -104, 13), s( -45, -93)], - [s( 3, -4), s( 4, -14), s( 3, -3), s( 25, -5), s( 2, -14), s( 87, -35), s( 6, -22), s( 61, -27)], - [s( 1, -22), s( 14, -1), s( 55, 42), s( 65, 44), s( 117, 22), s( 122, 14), s( 50, -17), s( 45, -39)], - [s( 3, -7), s( -14, 21), s( 33, 57), s( 65, 58), s( 37, 60), s( 70, 55), s( 3, 19), s( 52, -19)], - [s( -15, -5), s( -28, 7), s( 13, 58), s( 18, 59), s( 32, 63), s( 22, 48), s( -1, 8), s( 1, -18)], - [s( -39, -27), s( -43, -1), s( -2, 30), s( 10, 49), s( 28, 45), s( 8, 23), s( -12, -8), s( -15, -26)], - [s( -26, 0), s( -35, -19), s( -47, -4), s( -20, -3), s( -22, -2), s( -21, -10), s( -10, -32), s( 10, 13)], - [s( -44, 7), s( 2, -11), s( -42, -28), s( -21, -23), s( -17, -19), s( -8, -35), s( 4, -2), s( 1, -13)], + [s( -110, -61), s( -136, 8), s( -77, -12), s( -29, -22), s( 14, -16), s( -67, -51), s( -109, 17), s( -47, -90)], + [s( 3, -2), s( 9, -14), s( -1, -6), s( 16, -4), s( -15, -13), s( 65, -33), s( 7, -20), s( 48, -22)], + [s( 5, -22), s( 15, -6), s( 58, 42), s( 64, 46), s( 93, 31), s( 94, 22), s( 21, -13), s( 19, -30)], + [s( 9, -7), s( -13, 16), s( 39, 56), s( 71, 58), s( 32, 65), s( 70, 56), s( -21, 23), s( 50, -16)], + [s( -8, -5), s( -24, 2), s( 22, 56), s( 25, 57), s( 39, 61), s( 28, 46), s( -2, 3), s( 6, -18)], + [s( -32, -28), s( -38, -8), s( 6, 27), s( 17, 47), s( 36, 43), s( 15, 20), s( -11, -13), s( -8, -26)], + [s( -19, 0), s( -28, -21), s( -44, -11), s( -17, -9), s( -20, -8), s( -18, -17), s( -8, -32), s( 14, 14)], + [s( -36, 6), s( 6, -11), s( -36, -29), s( -15, -24), s( -11, -20), s( -1, -37), s( 10, -1), s( 8, -14)], ]; pub const BISHOPS: PieceSquareTableDefinition = [ - [s( -22, 10), s( -66, 18), s( -58, 13), s( -116, 29), s( -85, 20), s( -66, 5), s( -34, 3), s( -57, 3)], - [s( -17, -10), s( -2, -5), s( -13, -4), s( -35, 0), s( 5, -15), s( 0, -12), s( 0, -1), s( -2, -10)], - [s( -3, 21), s( 18, 1), s( 11, 0), s( 32, -16), s( 16, -8), s( 70, -7), s( 47, -4), s( 43, 12)], - [s( -7, 12), s( -3, 10), s( 14, -2), s( 29, 15), s( 23, 1), s( 17, 4), s( 2, 3), s( -6, 12)], - [s( -7, 4), s( -12, 8), s( -12, 9), s( 19, 3), s( 13, 5), s( -9, 1), s( -14, 5), s( 10, -8)], - [s( 6, 7), s( 3, 4), s( 3, 1), s( -1, 1), s( 3, 5), s( 5, 1), s( 8, -6), s( 25, -5)], - [s( 21, 9), s( 15, -9), s( 17, -21), s( -6, -1), s( 4, -4), s( 21, -13), s( 37, 1), s( 20, -13)], - [s( 8, -3), s( 28, 5), s( 15, -6), s( -5, 1), s( 7, 1), s( 1, 11), s( 29, -15), s( 24, -20)], + [s( -19, 9), s( -63, 19), s( -55, 13), s( -117, 30), s( -91, 23), s( -71, 9), s( -36, 6), s( -60, 5)], + [s( -15, -11), s( 4, -7), s( -8, -5), s( -32, 0), s( 2, -12), s( -12, -9), s( -19, 3), s( -16, -6)], + [s( 1, 19), s( 21, -1), s( 16, -2), s( 28, -14), s( 8, -5), s( 52, -2), s( 31, 0), s( 22, 18)], + [s( -4, 10), s( 2, 8), s( 13, -1), s( 29, 16), s( 22, 3), s( 17, 5), s( 6, 0), s( -8, 12)], + [s( -3, 2), s( -11, 8), s( -9, 7), s( 21, 2), s( 17, 4), s( -2, -2), s( -9, 4), s( 14, -10)], + [s( 7, 6), s( 7, 3), s( 8, -1), s( 5, -2), s( 9, 2), s( 10, -1), s( 14, -8), s( 30, -6)], + [s( 23, 9), s( 19, -11), s( 21, -23), s( 0, -4), s( 10, -6), s( 25, -16), s( 41, -1), s( 25, -14)], + [s( 11, -4), s( 30, 4), s( 19, -8), s( 0, -2), s( 12, -2), s( 7, 8), s( 30, -17), s( 32, -24)], ]; pub const ROOKS: PieceSquareTableDefinition = [ - [s( 31, 11), s( 3, 24), s( 2, 37), s( 4, 30), s( 28, 20), s( 57, 9), s( 56, 7), s( 85, 0)], - [s( 1, 16), s( -5, 33), s( 18, 38), s( 43, 24), s( 27, 25), s( 64, 7), s( 61, -1), s( 104, -20)], - [s( -25, 16), s( 5, 18), s( -4, 21), s( -1, 18), s( 39, 0), s( 47, -8), s( 114, -21), s( 85, -28)], - [s( -34, 19), s( -21, 15), s( -25, 26), s( -18, 20), s( -12, 1), s( 2, -7), s( 19, -11), s( 24, -17)], - [s( -51, 8), s( -54, 12), s( -42, 13), s( -31, 10), s( -28, 5), s( -38, 1), s( -9, -13), s( -20, -17)], - [s( -53, 2), s( -51, 0), s( -39, -3), s( -33, 0), s( -23, -7), s( -21, -19), s( 17, -42), s( -9, -38)], - [s( -52, -6), s( -43, -4), s( -22, -4), s( -21, -2), s( -14, -13), s( -9, -22), s( 11, -32), s( -26, -23)], - [s( -28, -5), s( -25, -4), s( -12, 3), s( -2, -4), s( 5, -13), s( -5, -9), s( 8, -21), s( -21, -22)], + [s( 17, 14), s( -13, 27), s( -18, 42), s( -28, 39), s( -14, 31), s( 24, 18), s( 27, 13), s( 52, 7)], + [s( 4, 15), s( -5, 32), s( 17, 39), s( 39, 26), s( 19, 27), s( 38, 14), s( 38, 4), s( 76, -13)], + [s( -15, 13), s( 14, 16), s( 6, 19), s( 7, 16), s( 44, -1), s( 40, -6), s( 104, -18), s( 64, -23)], + [s( -22, 16), s( -9, 11), s( -12, 23), s( -6, 17), s( -1, -2), s( 6, -8), s( 16, -10), s( 21, -16)], + [s( -40, 5), s( -43, 9), s( -31, 10), s( -19, 8), s( -16, 2), s( -35, 1), s( -9, -13), s( -19, -18)], + [s( -43, 0), s( -40, -3), s( -27, -6), s( -23, -2), s( -12, -9), s( -17, -20), s( 17, -42), s( -4, -39)], + [s( -42, -8), s( -32, -7), s( -11, -7), s( -10, -5), s( -5, -16), s( -5, -23), s( 11, -34), s( -19, -26)], + [s( -18, -6), s( -15, -6), s( -1, 1), s( 8, -6), s( 14, -15), s( 2, -12), s( 12, -22), s( -12, -23)], ]; pub const QUEENS: PieceSquareTableDefinition = [ - [s( -13, -11), s( -45, 26), s( -18, 50), s( 24, 30), s( 27, 30), s( 36, 28), s( 96, -51), s( 34, -3)], - [s( -4, -23), s( -42, 17), s( -39, 62), s( -51, 85), s( -43, 110), s( 9, 56), s( -4, 33), s( 67, 21)], - [s( -3, -16), s( -15, -5), s( -23, 40), s( -10, 50), s( 4, 65), s( 63, 40), s( 79, -3), s( 84, 3)], - [s( -25, -5), s( -25, 6), s( -28, 21), s( -28, 41), s( -29, 63), s( -7, 53), s( 5, 46), s( 16, 37)], - [s( -19, -13), s( -31, 15), s( -30, 10), s( -20, 30), s( -20, 25), s( -20, 24), s( -7, 20), s( 7, 18)], - [s( -19, -26), s( -14, -16), s( -17, -3), s( -17, -12), s( -12, -5), s( -6, -4), s( 9, -19), s( 8, -21)], - [s( -4, -37), s( -10, -37), s( 2, -47), s( 8, -43), s( 3, -34), s( 17, -69), s( 24, -98), s( 52, -122)], - [s( -11, -38), s( -8, -46), s( 2, -50), s( 12, -30), s( 9, -54), s( -14, -45), s( 21, -78), s( 15, -79)], + [s( -28, -5), s( -65, 31), s( -51, 63), s( -23, 46), s( -38, 53), s( -43, 63), s( 39, -25), s( -14, 12)], + [s( 3, -24), s( -31, 13), s( -35, 61), s( -49, 82), s( -67, 116), s( -17, 60), s( -22, 38), s( 48, 24)], + [s( 6, -18), s( -5, -7), s( -10, 35), s( -10, 50), s( -8, 65), s( 11, 49), s( 37, 9), s( 12, 24)], + [s( -10, -6), s( -7, 3), s( -14, 21), s( -18, 46), s( -18, 56), s( -4, 44), s( 7, 39), s( 13, 24)], + [s( 0, -16), s( -15, 15), s( -12, 11), s( -3, 29), s( -1, 25), s( -4, 18), s( 8, 13), s( 18, 5)], + [s( -3, -26), s( 4, -18), s( 1, -4), s( 1, -11), s( 8, -6), s( 11, -7), s( 25, -24), s( 21, -28)], + [s( 13, -41), s( 8, -41), s( 20, -48), s( 27, -43), s( 22, -34), s( 35, -75), s( 41, -106), s( 66, -130)], + [s( 7, -42), s( 8, -48), s( 20, -51), s( 30, -32), s( 26, -55), s( 3, -53), s( 34, -83), s( 29, -82)], ]; pub const KING: PieceSquareTableDefinition = [ - [s( 33, -113), s( 16, -44), s( 68, -32), s( -137, 38), s( -68, 12), s( 2, 14), s( 60, 3), s( 158, -138)], - [s( -138, 18), s( -65, 57), s( -120, 74), s( 27, 48), s( -48, 78), s( -46, 95), s( -4, 81), s( -40, 37)], - [s( -162, 39), s( -8, 65), s( -102, 92), s( -127, 107), s( -76, 106), s( 25, 96), s( -8, 93), s( -60, 52)], - [s( -120, 25), s( -134, 73), s( -156, 99), s( -215, 116), s( -204, 116), s( -152, 108), s( -152, 96), s( -191, 60)], - [s( -114, 8), s( -125, 52), s( -166, 86), s( -208, 106), s( -209, 106), s( -155, 86), s( -161, 70), s( -198, 47)], - [s( -58, -6), s( -36, 28), s( -113, 57), s( -132, 74), s( -123, 73), s( -120, 61), s( -59, 34), s( -83, 17)], - [s( 62, -34), s( 5, 3), s( -15, 21), s( -60, 36), s( -64, 41), s( -39, 27), s( 26, 1), s( 37, -24)], - [s( 46, -83), s( 90, -58), s( 58, -30), s( -71, -5), s( 14, -34), s( -38, -9), s( 63, -47), s( 58, -88)], + [s( 31, -118), s( 13, -47), s( 73, -37), s( -124, 32), s( -51, 7), s( 6, 11), s( 59, 0), s( 163, -142)], + [s( -124, 13), s( -22, 48), s( -78, 65), s( 70, 39), s( -5, 69), s( -4, 86), s( 28, 74), s( -38, 35)], + [s( -152, 35), s( 22, 58), s( -76, 85), s( -96, 99), s( -44, 99), s( 53, 89), s( 12, 88), s( -46, 47)], + [s( -110, 21), s( -93, 64), s( -118, 90), s( -176, 107), s( -164, 107), s( -115, 99), s( -116, 88), s( -184, 57)], + [s( -103, 4), s( -83, 43), s( -115, 74), s( -161, 95), s( -152, 93), s( -105, 75), s( -114, 60), s( -191, 44)], + [s( -54, -10), s( -1, 19), s( -66, 47), s( -83, 63), s( -70, 61), s( -71, 49), s( -20, 24), s( -81, 14)], + [s( 51, -35), s( 16, 0), s( -1, 18), s( -47, 32), s( -45, 36), s( -26, 24), s( 34, -1), s( 27, -24)], + [s( 29, -84), s( 76, -56), s( 40, -26), s( -81, -3), s( -2, -28), s( -46, -7), s( 48, -43), s( 38, -85)], ]; pub const KNIGHT_MOBILITY: [PhasedEval; 9] = [ s( 0, 0), s( 0, 0), - s( 38, 139), - s( 89, 154), - s( 115, 194), + s( 40, 135), + s( 90, 149), + s( 115, 191), s( 0, 0), - s( 151, 195), + s( 154, 197), s( 0, 0), - s( 136, 175), + s( 134, 174), ]; pub const BISHOP_MOBILITY: [PhasedEval; 14] = [ s( 0, 0), - s( 56, 57), - s( 74, 70), - s( 84, 114), - s( 101, 127), - s( 109, 139), - s( 126, 162), - s( 138, 169), - s( 147, 185), - s( 149, 190), - s( 156, 199), - s( 160, 193), - s( 161, 193), - s( 198, 179), + s( 63, 61), + s( 77, 70), + s( 86, 114), + s( 104, 126), + s( 111, 139), + s( 128, 162), + s( 138, 170), + s( 147, 186), + s( 148, 191), + s( 153, 201), + s( 155, 196), + s( 152, 198), + s( 179, 187), ]; pub const ROOK_MOBILITY: [PhasedEval; 15] = [ s( 0, 0), s( 0, 0), - s( 127, 255), - s( 139, 271), - s( 149, 282), - s( 156, 287), - s( 159, 292), - s( 164, 300), - s( 172, 302), - s( 182, 306), - s( 192, 313), - s( 201, 315), - s( 207, 321), - s( 219, 325), - s( 225, 326), + s( 135, 258), + s( 146, 274), + s( 156, 284), + s( 163, 289), + s( 166, 294), + s( 170, 301), + s( 177, 303), + s( 186, 307), + s( 195, 313), + s( 202, 316), + s( 207, 322), + s( 215, 327), + s( 216, 328), ]; pub const QUEEN_MOBILITY: [PhasedEval; 28] = [ s( 0, 0), s( 0, 0), s( 0, 0), - s( 374, 117), - s( 326, 240), - s( 361, 325), - s( 361, 366), - s( 361, 449), - s( 368, 469), - s( 369, 494), - s( 375, 502), - s( 379, 518), - s( 382, 533), - s( 386, 538), - s( 391, 545), - s( 392, 557), - s( 393, 567), - s( 396, 577), - s( 396, 586), - s( 398, 593), - s( 400, 606), - s( 406, 605), - s( 407, 609), - s( 420, 605), - s( 422, 604), - s( 440, 603), - s( 504, 566), - s( 569, 547), + s( 357, 100), + s( 333, 260), + s( 365, 337), + s( 365, 382), + s( 364, 461), + s( 371, 480), + s( 371, 502), + s( 377, 510), + s( 381, 524), + s( 384, 539), + s( 388, 544), + s( 392, 550), + s( 392, 562), + s( 392, 571), + s( 394, 581), + s( 394, 590), + s( 395, 596), + s( 396, 608), + s( 400, 607), + s( 401, 610), + s( 411, 606), + s( 412, 605), + s( 425, 605), + s( 487, 570), + s( 546, 548), ]; -pub const BISHOP_PAIR_BONUS: PhasedEval = s( 27, 90); +pub const ATTACKED_KING_SQUARES: [PhasedEval; 9] = [ + s( 61, -27), + s( 57, -20), + s( 27, -6), + s( -26, -8), + s( -116, 24), + s( -231, 83), + s( -349, 139), + s( -508, 195), + s( -286, -81), +]; + +pub const BISHOP_PAIR_BONUS: PhasedEval = s( 28, 88); diff --git a/src/utils/tuner/parameters.rs b/src/utils/tuner/parameters.rs index c805d7d..2af41a3 100644 --- a/src/utils/tuner/parameters.rs +++ b/src/utils/tuner/parameters.rs @@ -42,6 +42,8 @@ pub struct Parameters { rook_mobility: [PhasedEval; 15], queen_mobility: [PhasedEval; 28], + attacked_king_squares: [PhasedEval; 9], + bishop_pair: [PhasedEval; 1], } @@ -62,6 +64,8 @@ impl Parameters { rook_mobility: [PhasedEval::ZERO; 15], queen_mobility: [PhasedEval::ZERO; 28], + attacked_king_squares: [PhasedEval::ZERO; 9], + bishop_pair: [PhasedEval::ZERO; 1], } } @@ -87,6 +91,7 @@ impl Parameters { .copy_to(&mut parameter_components.bishop_mobility) .copy_to(&mut parameter_components.rook_mobility) .copy_to(&mut parameter_components.queen_mobility) + .copy_to(&mut parameter_components.attacked_king_squares) .copy_to(&mut parameter_components.bishop_pair); parameter_components.rebalance(); @@ -226,6 +231,7 @@ impl std::fmt::Display for Parameters { print_array(f, &self.bishop_mobility, "BISHOP_MOBILITY")?; print_array(f, &self.rook_mobility, "ROOK_MOBILITY")?; print_array(f, &self.queen_mobility, "QUEEN_MOBILITY")?; + print_array(f, &self.attacked_king_squares, "ATTACKED_KING_SQUARES")?; print_single(f, self.bishop_pair, "BISHOP_PAIR_BONUS")?; Ok(()) diff --git a/src/utils/tuner/trace.rs b/src/utils/tuner/trace.rs index 2ba23bc..614a979 100644 --- a/src/utils/tuner/trace.rs +++ b/src/utils/tuner/trace.rs @@ -1,3 +1,4 @@ +use crate::chess::bitboard::Bitboard; use crate::chess::board::Board; use crate::chess::game::Game; use crate::chess::movegen::tables; @@ -36,6 +37,8 @@ pub struct Trace { rook_mobility: [TraceComponent; 15], queen_mobility: [TraceComponent; 28], + attacked_king_squares: [TraceComponent; 9], + bishop_pair: TraceComponent, } @@ -45,6 +48,8 @@ impl Trace { fn trace_for_player(trace: &mut Self, board: &Board, player: Player) { let mut number_of_bishops = 0; + let mut attacked_squares = Bitboard::EMPTY; + let occupancy = board.occupancy(); for sq in board.pawns(player) { @@ -56,7 +61,10 @@ impl Trace { trace.material[PieceKind::Knight.array_idx()].incr(player); trace.knight_pst[sq.array_idx()].incr(player); - let mobility = tables::knight_attacks(sq).count(); + let attacks = tables::knight_attacks(sq); + attacked_squares |= attacks; + + let mobility = attacks.count(); trace.knight_mobility[mobility as usize].incr(player); } @@ -64,7 +72,10 @@ impl Trace { trace.material[PieceKind::Bishop.array_idx()].incr(player); trace.bishop_pst[sq.array_idx()].incr(player); - let mobility = tables::bishop_attacks(sq, occupancy).count(); + let attacks = tables::bishop_attacks(sq, occupancy); + attacked_squares |= attacks; + + let mobility = attacks.count(); trace.bishop_mobility[mobility as usize].incr(player); number_of_bishops += 1; @@ -78,7 +89,10 @@ impl Trace { trace.material[PieceKind::Rook.array_idx()].incr(player); trace.rook_pst[sq.array_idx()].incr(player); - let mobility = tables::rook_attacks(sq, occupancy).count(); + let attacks = tables::rook_attacks(sq, occupancy); + attacked_squares |= attacks; + + let mobility = attacks.count(); trace.rook_mobility[mobility as usize].incr(player); } @@ -86,9 +100,11 @@ impl Trace { trace.material[PieceKind::Queen.array_idx()].incr(player); trace.queen_pst[sq.array_idx()].incr(player); - let mobility = (tables::rook_attacks(sq, occupancy) - | tables::bishop_attacks(sq, occupancy)) - .count(); + let attacks = + tables::rook_attacks(sq, occupancy) | tables::bishop_attacks(sq, occupancy); + attacked_squares |= attacks; + + let mobility = attacks.count(); trace.queen_mobility[mobility as usize].incr(player); } @@ -96,6 +112,11 @@ impl Trace { trace.material[PieceKind::King.array_idx()].incr(player); trace.king_pst[sq.array_idx()].incr(player); } + + let enemy_king = board.king(player.other()).single(); + let enemy_king_surrounding_squares = tables::king_attacks(enemy_king); + let attacks_on_enemy_king = attacked_squares & enemy_king_surrounding_squares; + trace.attacked_king_squares[attacks_on_enemy_king.count() as usize].incr(player.other()); } pub fn for_game(game: &Game) -> Self { @@ -113,6 +134,8 @@ impl Trace { rook_mobility: [TraceComponent::default(); 15], queen_mobility: [TraceComponent::default(); 28], + attacked_king_squares: [TraceComponent::default(); 9], + bishop_pair: TraceComponent::default(), }; @@ -135,6 +158,7 @@ impl Trace { .add(&self.bishop_mobility) .add(&self.rook_mobility) .add(&self.queen_mobility) + .add(&self.attacked_king_squares) .add(&[self.bishop_pair]) .get() }