From fc0af41e6ec68c076e524fb0ad746adc9a1e4002 Mon Sep 17 00:00:00 2001 From: TheRealGioviok <425gioviok@gmail.com> Date: Sat, 7 Feb 2026 04:03:40 +0100 Subject: [PATCH 1/2] optimtry --- src/eval_constants.hpp | 1 + src/evaltune_main.cpp | 1 + src/evaluation.cpp | 102 ++++++++++++++++++++++++----------------- 3 files changed, 61 insertions(+), 43 deletions(-) diff --git a/src/eval_constants.hpp b/src/eval_constants.hpp index 0f1cf264..731a9040 100644 --- a/src/eval_constants.hpp +++ b/src/eval_constants.hpp @@ -174,6 +174,7 @@ inline TunableSigmoid<32> KING_SAFETY_ACTIVATION( inline VParam WINNABLE_PAWNS = V(-15); inline VParam WINNABLE_SYM = V(135); inline VParam WINNABLE_ASYM = V(123); +inline VParam WINNABLE_PAWN_ENDGAME = V(169); inline VParam WINNABLE_BIAS = V(-642); // Epoch duration: 7.52381s diff --git a/src/evaltune_main.cpp b/src/evaltune_main.cpp index 2fd2425c..bfbfbfeb 100644 --- a/src/evaltune_main.cpp +++ b/src/evaltune_main.cpp @@ -417,6 +417,7 @@ int main() { std::cout << "inline VParam WINNABLE_PAWNS = " << WINNABLE_PAWNS << ";\n"; std::cout << "inline VParam WINNABLE_SYM = " << WINNABLE_SYM << ";\n"; std::cout << "inline VParam WINNABLE_ASYM = " << WINNABLE_ASYM << ";\n"; + std::cout << "inline VParam WINNABLE_PAWN_ENDGAME = " << WINNABLE_PAWN_ENDGAME << ";\n"; std::cout << "inline VParam WINNABLE_BIAS = " << WINNABLE_BIAS << ";\n"; std::cout << std::endl; diff --git a/src/evaluation.cpp b/src/evaluation.cpp index 55cb8d7b..300ada9d 100644 --- a/src/evaluation.cpp +++ b/src/evaluation.cpp @@ -229,7 +229,7 @@ PScore evaluate_pawn_push_threats(const Position& pos) { } template -PScore evaluate_pieces(const Position& pos) { +PScore evaluate_pieces(const Position& pos, bool pawn_endgame) { constexpr Color opp = ~color; PScore eval = PSCORE_ZERO; Bitboard own_pawns = pos.bitboard_for(color, PieceType::Pawn); @@ -239,44 +239,47 @@ PScore evaluate_pieces(const Position& pos) { ? Bitboard::rank_mask(1) | Bitboard::rank_mask(2) : Bitboard::rank_mask(5) | Bitboard::rank_mask(6); Bitboard own_early_pawns = own_pawns & early_ranks; - Bitboard bb = (blocked_pawns | own_early_pawns) | pos.attacked_by(opp, PieceType::Pawn); - Bitboard bb2 = bb; - for (PieceId id : pos.get_piece_mask(color, PieceType::Knight)) { - eval += KNIGHT_MOBILITY[pos.mobility_of(color, id, ~bb)]; - } - for (PieceId id : pos.get_piece_mask(color, PieceType::Bishop)) { - eval += BISHOP_MOBILITY[pos.mobility_of(color, id, ~bb)]; - Square sq = pos.piece_list_sq(color)[id]; - eval += BISHOP_PAWNS[std::min( - static_cast(8), - (own_pawns & Bitboard::squares_of_color(sq.color())) - .popcount()) // Weird non standard positions which can have more than 8 pawns - ] + Bitboard bb = (blocked_pawns | own_early_pawns) | pos.attacked_by(opp, PieceType::Pawn); + if (!pawn_endgame) { + Bitboard bb2 = bb; + for (PieceId id : pos.get_piece_mask(color, PieceType::Knight)) { + eval += KNIGHT_MOBILITY[pos.mobility_of(color, id, ~bb)]; + } + for (PieceId id : pos.get_piece_mask(color, PieceType::Bishop)) { + eval += BISHOP_MOBILITY[pos.mobility_of(color, id, ~bb)]; + Square sq = pos.piece_list_sq(color)[id]; + eval += + BISHOP_PAWNS[std::min( + static_cast(8), + (own_pawns & Bitboard::squares_of_color(sq.color())) + .popcount()) // Weird non standard positions which can have more than 8 pawns + ] * (!pos.is_square_attacked_by(sq, color, PieceType::Pawn) + (blocked_pawns & Bitboard::central_files()).ipopcount()); - } - bb2 |= pos.attacked_by(opp, PieceType::Knight) | pos.attacked_by(opp, PieceType::Bishop); - for (PieceId id : pos.get_piece_mask(color, PieceType::Rook)) { - eval += ROOK_MOBILITY[pos.mobility_of(color, id, ~bb)]; - eval += ROOK_MOBILITY[pos.mobility_of(color, id, ~bb2)]; - // Rook lineups - Bitboard rook_file = Bitboard::file_mask(pos.piece_list_sq(color)[id].file()); - eval += ROOK_LINEUP - * (rook_file - & (pos.bitboard_for(~color, PieceType::Queen) - | pos.bitboard_for(color, PieceType::Queen))) - .ipopcount(); - } - bb2 |= pos.attacked_by(opp, PieceType::Rook); - for (PieceId id : pos.get_piece_mask(color, PieceType::Queen)) { - eval += QUEEN_MOBILITY[pos.mobility_of(color, id, ~bb)]; - eval += QUEEN_MOBILITY[pos.mobility_of(color, id, ~bb2)]; + } + bb2 |= pos.attacked_by(opp, PieceType::Knight) | pos.attacked_by(opp, PieceType::Bishop); + for (PieceId id : pos.get_piece_mask(color, PieceType::Rook)) { + eval += ROOK_MOBILITY[pos.mobility_of(color, id, ~bb)]; + eval += ROOK_MOBILITY[pos.mobility_of(color, id, ~bb2)]; + // Rook lineups + Bitboard rook_file = Bitboard::file_mask(pos.piece_list_sq(color)[id].file()); + eval += ROOK_LINEUP + * (rook_file + & (pos.bitboard_for(~color, PieceType::Queen) + | pos.bitboard_for(color, PieceType::Queen))) + .ipopcount(); + } + bb2 |= pos.attacked_by(opp, PieceType::Rook); + for (PieceId id : pos.get_piece_mask(color, PieceType::Queen)) { + eval += QUEEN_MOBILITY[pos.mobility_of(color, id, ~bb)]; + eval += QUEEN_MOBILITY[pos.mobility_of(color, id, ~bb2)]; + } + if (pos.piece_count(color, PieceType::Bishop) >= 2) { + eval += BISHOP_PAIR_VAL; + } } eval += KING_MOBILITY[pos.mobility_of(color, PieceId::king(), ~bb)]; - if (pos.piece_count(color, PieceType::Bishop) >= 2) { - eval += BISHOP_PAIR_VAL; - } return eval; } @@ -415,7 +418,7 @@ PScore king_safety_activation(const Position& pos, PScore& king_safety_score) { return activated; } -PScore apply_winnable(const Position& pos, PScore& score) { +PScore apply_winnable(const Position& pos, PScore& score, bool is_pawn_endgame) { Bitboard white_pawns = pos.bitboard_for(Color::White, PieceType::Pawn); Bitboard black_pawns = pos.bitboard_for(Color::Black, PieceType::Pawn); @@ -452,18 +455,31 @@ Score evaluate_white_pov(const Position& pos, const PsqtState& psqt_state) { * (pos.piece_count(Color::White, PieceType::Queen) + pos.piece_count(Color::Black, PieceType::Queen)); - phase = std::min(phase, 24); + // TODO: replace this with endgame routing + bool pawn_endgame = phase == 0; + PScore eval = psqt_state.score(); // Used for linear components - eval += evaluate_pieces(pos) - evaluate_pieces(pos); + // pawn eval eval += evaluate_pawns(pos) - evaluate_pawns(pos); - eval += - evaluate_pawn_push_threats(pos) - evaluate_pawn_push_threats(pos); + eval += evaluate_potential_checkers(pos) - evaluate_potential_checkers(pos); - eval += evaluate_threats(pos) - evaluate_threats(pos); - eval += evaluate_space(pos) - evaluate_space(pos); - eval += evaluate_outposts(pos) - evaluate_outposts(pos); + + eval += evaluate_pieces(pos, pawn_endgame) + - evaluate_pieces(pos, pawn_endgame); + + if (!pawn_endgame) { + + phase = std::min(phase, 24); + + + eval += evaluate_pawn_push_threats(pos) + - evaluate_pawn_push_threats(pos); + eval += evaluate_threats(pos) - evaluate_threats(pos); + eval += evaluate_space(pos) - evaluate_space(pos); + eval += evaluate_outposts(pos) - evaluate_outposts(pos); + } // Nonlinear king safety components PScore white_king_attack_total = evaluate_king_safety(pos); @@ -476,7 +492,7 @@ Score evaluate_white_pov(const Position& pos, const PsqtState& psqt_state) { eval += (us == Color::White) ? TEMPO_VAL : -TEMPO_VAL; // Winnable - eval = apply_winnable(pos, eval); + eval = apply_winnable(pos, eval, pawn_endgame); return static_cast(eval.phase<24>(static_cast(phase))); }; From 95e4173b5d9dfd67dbcb44c9efd85a4daaf8fbb1 Mon Sep 17 00:00:00 2001 From: TheRealGioviok <425gioviok@gmail.com> Date: Sat, 7 Feb 2026 14:13:39 +0100 Subject: [PATCH 2/2] Bench: 16395475 --- src/eval_constants.hpp | 192 ++++++++++++++++++++--------------------- src/evaluation.cpp | 109 +++++++++++------------ 2 files changed, 148 insertions(+), 153 deletions(-) diff --git a/src/eval_constants.hpp b/src/eval_constants.hpp index 731a9040..d514def1 100644 --- a/src/eval_constants.hpp +++ b/src/eval_constants.hpp @@ -5,177 +5,177 @@ namespace Clockwork { // clang-format off -inline const PParam PAWN_MAT = S(136, 203); -inline const PParam KNIGHT_MAT = S(575, 624); -inline const PParam BISHOP_MAT = S(605, 648); -inline const PParam ROOK_MAT = S(474, 682); -inline const PParam QUEEN_MAT = S(1095, 1087); -inline const PParam TEMPO_VAL = S(57, 21); - -inline const PParam BISHOP_PAIR_VAL = S(52, 196); +inline const PParam PAWN_MAT = S(136, 201); +inline const PParam KNIGHT_MAT = S(569, 624); +inline const PParam BISHOP_MAT = S(603, 648); +inline const PParam ROOK_MAT = S(469, 678); +inline const PParam QUEEN_MAT = S(1101, 1088); +inline const PParam TEMPO_VAL = S(58, 21); + +inline const PParam BISHOP_PAIR_VAL = S(52, 197); inline const PParam ROOK_OPEN_VAL = S(105, -11); -inline const PParam ROOK_SEMIOPEN_VAL = S(43, 22); +inline const PParam ROOK_SEMIOPEN_VAL = S(44, 21); inline const PParam DOUBLED_PAWN_VAL = S(-7, -70); inline const PParam ISOLATED_PAWN_VAL = S(-19, -17); -inline const PParam POTENTIAL_CHECKER_VAL = S(-49, -24); -inline const PParam OUTPOST_KNIGHT_VAL = S(36, 64); -inline const PParam OUTPOST_BISHOP_VAL = S(50, 39); +inline const PParam POTENTIAL_CHECKER_VAL = S(-49, -25); +inline const PParam OUTPOST_KNIGHT_VAL = S(35, 66); +inline const PParam OUTPOST_BISHOP_VAL = S(49, 40); inline const PParam PAWN_PUSH_THREAT_KNIGHT = S(42, 7); -inline const PParam PAWN_PUSH_THREAT_BISHOP = S(54, -19); -inline const PParam PAWN_PUSH_THREAT_ROOK = S(27, 53); +inline const PParam PAWN_PUSH_THREAT_BISHOP = S(54, -18); +inline const PParam PAWN_PUSH_THREAT_ROOK = S(26, 55); inline const PParam PAWN_PUSH_THREAT_QUEEN = S(67, -36); inline const std::array PAWN_PHALANX = { - S(16, 1), S(38, 27), S(57, 51), S(136, 145), S(383, 197), S(456, 694), + S(16, 1), S(38, 27), S(57, 51), S(135, 146), S(377, 206), S(459, 690), }; inline const std::array DEFENDED_PAWN = { - S(54, 35), S(44, 27), S(53, 55), S(118, 140), S(411, 79), + S(54, 35), S(44, 27), S(54, 54), S(117, 142), S(403, 90), }; inline const std::array PASSED_PAWN = { - S(-70, -121), S(-67, -98), S(-47, 14), S(9, 122), S(91, 268), S(261, 382), + S(-71, -121), S(-67, -99), S(-46, 13), S(11, 119), S(92, 268), S(264, 380), }; inline const std::array DEFENDED_PASSED_PUSH = { - S(36, -45), S(35, -5), S(23, 31), S(1, 107), S(46, 219), S(200, 280), + S(36, -45), S(34, -4), S(22, 31), S(1, 109), S(47, 221), S(200, 283), }; inline const std::array BLOCKED_PASSED_PAWN = { - S(23, -38), S(2, 13), S(3, -21), S(1, -56), S(-6, -128), S(-204, -238), + S(22, -37), S(3, 12), S(3, -21), S(-1, -53), S(-8, -126), S(-211, -232), }; inline const std::array FRIENDLY_KING_PASSED_PAWN_DISTANCE = { - S(0, 0), S(-9, 151), S(-18, 113), S(-11, 43), S(-3, 6), S(2, 5), S(37, 5), S(10, -1), + S(0, 0), S(-5, 149), S(-16, 113), S(-12, 45), S(-5, 9), S(0, 8), S(36, 6), S(10, 1), }; inline const std::array ENEMY_KING_PASSED_PAWN_DISTANCE = { - S(0, 0), S(-314, -47), S(-47, 30), S(-27, 61), S(12, 96), S(31, 112), S(49, 112), S(30, 105), + S(0, 0), S(-306, -54), S(-42, 26), S(-26, 61), S(11, 97), S(30, 114), S(48, 114), S(29, 107), }; inline const std::array KNIGHT_MOBILITY = { - S(56, 0), S(127, 171), S(162, 261), S(190, 297), S(230, 315), S(254, 350), S(286, 347), S(317, 361), S(371, 274), + S(66, 3), S(137, 174), S(172, 264), S(200, 300), S(240, 318), S(264, 353), S(296, 350), S(327, 364), S(380, 278), }; inline const std::array BISHOP_MOBILITY = { - S(90, 2), S(133, 175), S(187, 239), S(214, 284), S(239, 315), S(255, 339), S(262, 359), S(276, 369), S(282, 386), S(307, 368), S(317, 371), S(366, 317), S(364, 332), S(394, 279), + S(89, 0), S(132, 174), S(186, 238), S(213, 282), S(238, 314), S(254, 339), S(261, 358), S(275, 368), S(281, 386), S(306, 367), S(316, 369), S(364, 317), S(362, 332), S(393, 278), }; inline const std::array ROOK_MOBILITY = { - S(307, 241), S(226, 420), S(251, 445), S(268, 455), S(279, 467), S(286, 478), S(292, 488), S(301, 490), S(307, 501), S(318, 502), S(330, 503), S(337, 508), S(342, 507), S(359, 479), S(446, 374), + S(312, 247), S(231, 426), S(256, 451), S(273, 460), S(284, 473), S(291, 484), S(297, 494), S(306, 496), S(312, 507), S(323, 508), S(334, 509), S(342, 514), S(347, 513), S(364, 485), S(449, 382), }; inline const std::array QUEEN_MOBILITY = { - S(493, 512), S(633, 531), S(658, 643), S(676, 754), S(692, 801), S(700, 845), S(706, 877), S(714, 887), S(717, 911), S(721, 925), S(726, 932), S(731, 940), S(740, 933), S(742, 938), S(747, 934), S(745, 938), S(747, 933), S(754, 925), S(761, 916), S(770, 910), S(778, 887), S(801, 847), S(800, 844), S(797, 791), S(786, 777), S(777, 749), S(709, 810), S(733, 714), + S(494, 513), S(635, 531), S(659, 644), S(677, 756), S(693, 802), S(702, 847), S(708, 878), S(715, 889), S(719, 912), S(722, 927), S(728, 934), S(732, 942), S(741, 935), S(743, 941), S(748, 935), S(746, 940), S(749, 934), S(755, 928), S(762, 920), S(772, 912), S(780, 889), S(802, 849), S(800, 848), S(797, 794), S(785, 781), S(780, 749), S(712, 808), S(735, 713), }; inline const std::array KING_MOBILITY = { - S(496, -200), S(107, -106), S(29, -28), S(16, 6), S(-3, 5), S(-20, 1), S(-25, 8), S(-41, 16), S(-31, -22), + S(497, -203), S(104, -103), S(26, -24), S(13, 9), S(-6, 9), S(-22, 1), S(-27, 8), S(-41, 14), S(-28, -28), }; inline const std::array PT_INNER_RING_ATTACKS = { - S(12, -8), S(16, -15), S(13, -12), S(6, -8), S(2, 205), + S(12, -7), S(16, -15), S(13, -12), S(6, -8), S(2, 205), }; inline const std::array PT_OUTER_RING_ATTACKS = { - S(4, -0), S(7, -11), S(6, -9), S(5, -5), S(6, 414), + S(4, -0), S(7, -11), S(6, -9), S(5, -5), S(6, 416), }; -inline const PParam PAWN_THREAT_KNIGHT = S(212, 92); +inline const PParam PAWN_THREAT_KNIGHT = S(213, 93); inline const PParam PAWN_THREAT_BISHOP = S(190, 143); -inline const PParam PAWN_THREAT_ROOK = S(192, 123); -inline const PParam PAWN_THREAT_QUEEN = S(167, -17); +inline const PParam PAWN_THREAT_ROOK = S(191, 124); +inline const PParam PAWN_THREAT_QUEEN = S(166, -16); inline const PParam KNIGHT_THREAT_BISHOP = S(109, 101); -inline const PParam KNIGHT_THREAT_ROOK = S(225, 68); -inline const PParam KNIGHT_THREAT_QUEEN = S(150, -2); +inline const PParam KNIGHT_THREAT_ROOK = S(227, 67); +inline const PParam KNIGHT_THREAT_QUEEN = S(151, -2); inline const PParam BISHOP_THREAT_KNIGHT = S(105, 57); inline const PParam BISHOP_THREAT_ROOK = S(212, 124); -inline const PParam BISHOP_THREAT_QUEEN = S(175, 98); +inline const PParam BISHOP_THREAT_QUEEN = S(175, 100); inline const std::array BISHOP_PAWNS = { - S(9, -35), S(-4, -9), S(-6, -18), S(-9, -28), S(-13, -37), S(-18, -42), S(-20, -55), S(-27, -52), S(-38, -53), + S(9, -36), S(-4, -9), S(-6, -18), S(-9, -28), S(-13, -37), S(-18, -42), S(-21, -54), S(-28, -52), S(-39, -52), }; -inline const PParam ROOK_LINEUP = S(12, 66); +inline const PParam ROOK_LINEUP = S(12, 67); inline const std::array PAWN_PSQT = { - S(294, 346), S(145, 444), S(290, 413), S(303, 278), S(320, 238), S(214, 322), S(151, 359), S(258, 315), // - S(114, 212), S(145, 252), S(186, 167), S(172, 103), S(152, 86), S(125, 139), S(95, 197), S(47, 222), // - S(80, 174), S(67, 176), S(110, 101), S(111, 79), S(100, 76), S(71, 109), S(23, 159), S(10, 188), // - S(57, 125), S(46, 149), S(82, 96), S(79, 88), S(58, 91), S(40, 117), S(-20, 160), S(-20, 152), // - S(56, 98), S(95, 105), S(80, 137), S(72, 122), S(44, 118), S(21, 125), S(-13, 142), S(-21, 135), // - S(69, 100), S(158, 116), S(143, 172), S(94, 154), S(66, 141), S(45, 136), S(15, 148), S(-3, 150), // + S(298, 344), S(147, 444), S(293, 412), S(301, 281), S(323, 237), S(217, 320), S(155, 357), S(264, 311), // + S(119, 208), S(150, 248), S(189, 166), S(173, 103), S(154, 85), S(127, 138), S(99, 194), S(50, 221), // + S(82, 173), S(69, 176), S(111, 102), S(112, 80), S(101, 77), S(73, 109), S(25, 159), S(12, 187), // + S(58, 125), S(48, 149), S(84, 97), S(80, 89), S(59, 92), S(42, 117), S(-18, 160), S(-18, 152), // + S(57, 99), S(96, 106), S(81, 137), S(73, 123), S(45, 119), S(23, 125), S(-12, 142), S(-20, 136), // + S(70, 101), S(160, 116), S(145, 172), S(95, 155), S(67, 142), S(46, 136), S(17, 148), S(-2, 150), // }; inline const std::array KNIGHT_PSQT = { - S(-251, -76), S(-156, 196), S(-102, 47), S(94, 182), S(32, 184), S(-115, 189), S(-246, 237), S(-291, -3), // - S(75, 159), S(116, 187), S(204, 145), S(197, 156), S(194, 162), S(111, 187), S(74, 203), S(48, 180), // - S(159, 156), S(206, 152), S(207, 209), S(208, 193), S(167, 229), S(107, 244), S(119, 189), S(84, 182), // - S(227, 178), S(235, 198), S(231, 223), S(218, 254), S(219, 262), S(173, 248), S(166, 216), S(161, 188), // - S(210, 183), S(245, 165), S(214, 223), S(211, 242), S(187, 247), S(185, 231), S(182, 181), S(145, 188), // - S(155, 149), S(180, 159), S(170, 197), S(178, 224), S(174, 223), S(138, 203), S(128, 171), S(100, 136), // - S(166, 152), S(187, 150), S(155, 159), S(156, 183), S(148, 180), S(121, 137), S(108, 157), S(95, 76), // - S(101, 104), S(147, 169), S(162, 136), S(179, 128), S(159, 152), S(127, 124), S(112, 148), S(75, 71), // + S(-253, -78), S(-155, 193), S(-101, 45), S(93, 182), S(30, 185), S(-116, 189), S(-250, 241), S(-292, -5), // + S(71, 162), S(114, 187), S(202, 145), S(197, 154), S(195, 159), S(108, 188), S(72, 204), S(46, 181), // + S(156, 158), S(204, 152), S(205, 209), S(206, 193), S(167, 227), S(106, 244), S(118, 188), S(83, 181), // + S(225, 178), S(234, 197), S(230, 222), S(217, 253), S(218, 261), S(172, 247), S(165, 215), S(160, 187), // + S(208, 182), S(244, 164), S(213, 222), S(209, 242), S(185, 247), S(184, 230), S(181, 179), S(144, 187), // + S(154, 147), S(179, 158), S(169, 196), S(177, 222), S(173, 221), S(137, 202), S(127, 169), S(98, 136), // + S(165, 151), S(186, 148), S(154, 157), S(155, 181), S(147, 179), S(119, 136), S(107, 156), S(95, 72), // + S(100, 102), S(145, 169), S(161, 134), S(177, 126), S(158, 150), S(126, 123), S(111, 148), S(73, 69), // }; inline const std::array BISHOP_PSQT = { - S(-2, 293), S(-17, 304), S(-279, 348), S(-144, 284), S(-155, 306), S(-169, 304), S(-52, 300), S(30, 273), // - S(121, 202), S(61, 285), S(94, 240), S(40, 259), S(56, 257), S(81, 257), S(119, 252), S(95, 231), // - S(191, 235), S(204, 246), S(196, 256), S(173, 255), S(144, 251), S(152, 259), S(167, 251), S(164, 222), // - S(161, 224), S(197, 235), S(198, 255), S(194, 294), S(224, 282), S(155, 259), S(168, 223), S(125, 225), // - S(189, 184), S(206, 216), S(211, 240), S(215, 268), S(191, 283), S(177, 260), S(144, 238), S(141, 195), // - S(216, 191), S(249, 204), S(260, 231), S(205, 257), S(202, 235), S(196, 247), S(203, 224), S(144, 219), // - S(182, 165), S(281, 182), S(238, 196), S(205, 213), S(185, 217), S(189, 193), S(190, 190), S(183, 184), // - S(213, 167), S(201, 184), S(200, 217), S(214, 180), S(204, 191), S(204, 233), S(200, 212), S(192, 189), // + S(3, 296), S(-11, 307), S(-270, 347), S(-136, 285), S(-147, 306), S(-159, 302), S(-45, 302), S(36, 274), // + S(125, 208), S(67, 288), S(101, 240), S(47, 259), S(64, 257), S(88, 258), S(125, 253), S(101, 232), // + S(197, 236), S(208, 250), S(203, 257), S(179, 257), S(151, 252), S(158, 261), S(173, 253), S(170, 224), // + S(167, 228), S(202, 237), S(204, 257), S(200, 296), S(230, 285), S(161, 261), S(173, 226), S(132, 226), // + S(195, 187), S(211, 219), S(217, 242), S(221, 271), S(196, 286), S(182, 263), S(150, 240), S(146, 198), // + S(221, 193), S(255, 207), S(266, 234), S(211, 260), S(207, 237), S(202, 249), S(208, 226), S(149, 222), // + S(187, 167), S(287, 183), S(244, 197), S(211, 215), S(191, 219), S(195, 195), S(196, 192), S(189, 186), // + S(219, 168), S(207, 185), S(206, 220), S(220, 182), S(210, 193), S(209, 235), S(206, 215), S(198, 191), // }; inline const std::array ROOK_PSQT = { - S(425, 384), S(437, 403), S(413, 417), S(433, 378), S(413, 384), S(378, 396), S(374, 412), S(369, 415), // - S(303, 465), S(378, 462), S(453, 429), S(400, 433), S(385, 441), S(364, 446), S(297, 477), S(280, 483), // - S(272, 460), S(373, 448), S(430, 408), S(411, 395), S(362, 424), S(320, 447), S(323, 444), S(257, 484), // - S(276, 420), S(353, 429), S(389, 402), S(363, 406), S(354, 417), S(315, 439), S(311, 434), S(236, 461), // - S(259, 352), S(323, 370), S(312, 390), S(291, 387), S(268, 411), S(258, 424), S(228, 418), S(208, 415), // - S(251, 296), S(313, 323), S(299, 349), S(284, 347), S(271, 356), S(245, 379), S(243, 353), S(208, 361), // - S(144, 307), S(276, 273), S(285, 304), S(275, 326), S(260, 331), S(253, 334), S(235, 321), S(211, 331), // - S(208, 293), S(231, 313), S(287, 303), S(299, 300), S(288, 308), S(268, 323), S(257, 320), S(238, 328), // + S(426, 379), S(439, 398), S(414, 412), S(435, 373), S(414, 380), S(380, 390), S(375, 408), S(369, 411), // + S(301, 465), S(376, 461), S(453, 425), S(399, 431), S(384, 439), S(364, 444), S(297, 475), S(280, 481), // + S(270, 460), S(371, 447), S(429, 407), S(409, 393), S(361, 423), S(319, 446), S(322, 442), S(255, 484), // + S(275, 419), S(352, 428), S(387, 401), S(361, 405), S(352, 417), S(313, 438), S(309, 433), S(235, 461), // + S(257, 352), S(322, 369), S(311, 389), S(289, 386), S(266, 410), S(257, 422), S(227, 417), S(206, 414), // + S(249, 293), S(311, 322), S(297, 347), S(282, 345), S(270, 354), S(244, 376), S(242, 351), S(207, 358), // + S(142, 305), S(274, 271), S(285, 300), S(274, 323), S(259, 329), S(252, 332), S(234, 319), S(210, 328), // + S(207, 290), S(230, 311), S(286, 301), S(298, 298), S(287, 306), S(267, 321), S(256, 317), S(237, 326), // }; inline const std::array QUEEN_PSQT = { - S(553, 638), S(603, 589), S(528, 712), S(493, 783), S(478, 768), S(515, 706), S(534, 633), S(489, 669), // - S(553, 691), S(515, 789), S(503, 825), S(358, 922), S(365, 911), S(430, 855), S(475, 729), S(485, 709), // - S(514, 762), S(561, 782), S(494, 885), S(443, 903), S(417, 900), S(468, 818), S(504, 738), S(525, 657), // - S(554, 680), S(558, 767), S(493, 841), S(486, 869), S(477, 867), S(489, 773), S(531, 707), S(518, 672), // - S(568, 649), S(555, 721), S(525, 778), S(496, 818), S(494, 820), S(497, 766), S(514, 690), S(542, 610), // - S(548, 593), S(582, 643), S(573, 712), S(543, 705), S(539, 693), S(534, 720), S(549, 637), S(528, 609), // - S(529, 480), S(567, 493), S(570, 561), S(582, 599), S(569, 626), S(563, 590), S(525, 630), S(537, 605), // - S(511, 496), S(544, 343), S(567, 363), S(581, 474), S(577, 549), S(575, 496), S(564, 520), S(532, 549), // + S(550, 643), S(601, 593), S(523, 719), S(493, 785), S(476, 772), S(511, 713), S(533, 636), S(489, 670), // + S(550, 697), S(514, 793), S(503, 827), S(359, 923), S(366, 911), S(429, 859), S(475, 731), S(484, 714), // + S(513, 764), S(560, 784), S(492, 890), S(443, 906), S(416, 903), S(467, 821), S(504, 740), S(525, 657), // + S(553, 683), S(556, 772), S(492, 845), S(484, 873), S(477, 870), S(487, 777), S(530, 710), S(517, 676), // + S(567, 651), S(554, 724), S(525, 780), S(495, 822), S(493, 824), S(497, 768), S(514, 691), S(541, 612), // + S(547, 595), S(581, 645), S(573, 713), S(542, 707), S(539, 694), S(533, 722), S(549, 638), S(527, 611), // + S(529, 481), S(566, 495), S(570, 563), S(581, 601), S(568, 627), S(562, 592), S(525, 632), S(537, 606), // + S(511, 497), S(543, 343), S(567, 364), S(581, 474), S(576, 551), S(575, 497), S(563, 522), S(532, 550), // }; inline const std::array KING_PSQT = { - S(-69, -319), S(265, 196), S(140, 151), S(25, -28), S(0, 0), S(0, 0), S(0, 0), S(0, 0), // - S(212, -52), S(327, 175), S(185, 165), S(116, 3), S(0, 0), S(0, 0), S(0, 0), S(0, 0), // - S(202, 46), S(357, 119), S(250, 117), S(159, 6), S(0, 0), S(0, 0), S(0, 0), S(0, 0), // - S(54, 16), S(304, 59), S(158, 76), S(105, 33), S(0, 0), S(0, 0), S(0, 0), S(0, 0), // - S(-33, -18), S(219, 14), S(151, 20), S(27, 32), S(0, 0), S(0, 0), S(0, 0), S(0, 0), // - S(-23, -15), S(212, -3), S(114, 8), S(64, -11), S(0, 0), S(0, 0), S(0, 0), S(0, 0), // - S(1, -21), S(85, 32), S(2, 34), S(-55, 10), S(0, 0), S(0, 0), S(0, 0), S(0, 0), // - S(-112, -72), S(-13, -26), S(-113, -20), S(-116, -89), S(0, 0), S(0, 0), S(0, 0), S(0, 0), // + S(-58, -323), S(289, 177), S(160, 136), S(34, -31), S(0, 0), S(0, 0), S(0, 0), S(0, 0), // + S(231, -65), S(347, 162), S(202, 155), S(122, 4), S(0, 0), S(0, 0), S(0, 0), S(0, 0), // + S(227, 27), S(382, 105), S(268, 108), S(164, 8), S(0, 0), S(0, 0), S(0, 0), S(0, 0), // + S(83, -5), S(332, 43), S(180, 66), S(117, 30), S(0, 0), S(0, 0), S(0, 0), S(0, 0), // + S(-23, -26), S(229, 9), S(157, 18), S(39, 28), S(0, 0), S(0, 0), S(0, 0), S(0, 0), // + S(-23, -18), S(210, -1), S(113, 10), S(59, -6), S(0, 0), S(0, 0), S(0, 0), S(0, 0), // + S(-3, -20), S(81, 36), S(-3, 39), S(-60, 16), S(0, 0), S(0, 0), S(0, 0), S(0, 0), // + S(-115, -72), S(-17, -25), S(-117, -18), S(-120, -87), S(0, 0), S(0, 0), S(0, 0), S(0, 0), // }; inline const std::array, 4> KING_SHELTER = {{ - {{ S(20, -17), S(2, 19), S(-2, 21), S(5, 7), S(5, 4), S(-2, 21), S(4, 20), }}, - {{ S(10, -5), S(-18, 28), S(-14, 22), S(-5, 4), S(-4, 4), S(-13, 26), S(-17, 36), }}, - {{ S(-12, 3), S(-23, 28), S(-22, 10), S(-18, -5), S(-18, -3), S(-21, 10), S(-22, 25), }}, - {{ S(6, -15), S(-12, -15), S(-3, -19), S(2, -23), S(0, -21), S(-4, -16), S(-8, -16), }}, + {{ S(17, -17), S(-2, 18), S(-5, 20), S(2, 6), S(2, 2), S(-5, 20), S(0, 19), }}, + {{ S(6, -6), S(-21, 27), S(-17, 21), S(-8, 3), S(-8, 3), S(-17, 25), S(-20, 35), }}, + {{ S(-13, -0), S(-24, 25), S(-22, 7), S(-18, -7), S(-18, -6), S(-21, 7), S(-22, 22), }}, + {{ S(2, -16), S(-16, -16), S(-7, -19), S(-2, -23), S(-3, -22), S(-8, -17), S(-11, -17), }}, }}; inline const std::array BLOCKED_SHELTER_STORM = { - S(0, 0), S(0, 0), S(4, 23), S(-18, 31), S(-15, 19), S(-8, 7), S(-8, -8), + S(0, 0), S(0, 0), S(1, 26), S(-21, 33), S(-18, 22), S(-11, 10), S(-10, -7), }; inline const std::array, 4> SHELTER_STORM = {{ - {{ S(-4, 2), S(-15, 10), S(-13, 9), S(-12, 9), S(-13, 3), S(-11, -1), S(-15, 8), }}, - {{ S(-3, 1), S(-11, 7), S(-18, 12), S(-15, 9), S(-14, 5), S(-16, 9), S(-11, 6), }}, - {{ S(-10, 5), S(-14, 2), S(-15, 9), S(-11, 8), S(-11, 7), S(-15, 7), S(-14, 3), }}, - {{ S(-10, 7), S(-15, 9), S(-16, 8), S(-11, 12), S(-9, 12), S(-15, 8), S(-17, 8), }}, + {{ S(-7, 4), S(-17, 13), S(-16, 11), S(-15, 11), S(-15, 6), S(-14, 2), S(-17, 11), }}, + {{ S(-6, 3), S(-14, 9), S(-20, 14), S(-17, 12), S(-17, 8), S(-19, 11), S(-13, 8), }}, + {{ S(-12, 7), S(-17, 5), S(-18, 12), S(-14, 11), S(-13, 10), S(-17, 10), S(-16, 6), }}, + {{ S(-13, 9), S(-18, 11), S(-19, 11), S(-14, 15), S(-12, 15), S(-18, 11), S(-19, 11), }}, }}; inline TunableSigmoid<32> KING_SAFETY_ACTIVATION( - 1166, 539, -40, 58 + 1181, 554, -25, 55 ); inline VParam WINNABLE_PAWNS = V(-15); -inline VParam WINNABLE_SYM = V(135); -inline VParam WINNABLE_ASYM = V(123); -inline VParam WINNABLE_PAWN_ENDGAME = V(169); -inline VParam WINNABLE_BIAS = V(-642); +inline VParam WINNABLE_SYM = V(137); +inline VParam WINNABLE_ASYM = V(124); +inline VParam WINNABLE_PAWN_ENDGAME = V(225); +inline VParam WINNABLE_BIAS = V(-655); // Epoch duration: 7.52381s // clang-format on diff --git a/src/evaluation.cpp b/src/evaluation.cpp index 300ada9d..c7915be4 100644 --- a/src/evaluation.cpp +++ b/src/evaluation.cpp @@ -229,7 +229,7 @@ PScore evaluate_pawn_push_threats(const Position& pos) { } template -PScore evaluate_pieces(const Position& pos, bool pawn_endgame) { +PScore evaluate_pieces(const Position& pos) { constexpr Color opp = ~color; PScore eval = PSCORE_ZERO; Bitboard own_pawns = pos.bitboard_for(color, PieceType::Pawn); @@ -239,44 +239,41 @@ PScore evaluate_pieces(const Position& pos, bool pawn_endgame) { ? Bitboard::rank_mask(1) | Bitboard::rank_mask(2) : Bitboard::rank_mask(5) | Bitboard::rank_mask(6); Bitboard own_early_pawns = own_pawns & early_ranks; - Bitboard bb = (blocked_pawns | own_early_pawns) | pos.attacked_by(opp, PieceType::Pawn); - if (!pawn_endgame) { - Bitboard bb2 = bb; - for (PieceId id : pos.get_piece_mask(color, PieceType::Knight)) { - eval += KNIGHT_MOBILITY[pos.mobility_of(color, id, ~bb)]; - } - for (PieceId id : pos.get_piece_mask(color, PieceType::Bishop)) { - eval += BISHOP_MOBILITY[pos.mobility_of(color, id, ~bb)]; - Square sq = pos.piece_list_sq(color)[id]; - eval += - BISHOP_PAWNS[std::min( - static_cast(8), - (own_pawns & Bitboard::squares_of_color(sq.color())) - .popcount()) // Weird non standard positions which can have more than 8 pawns - ] + Bitboard bb = (blocked_pawns | own_early_pawns) | pos.attacked_by(opp, PieceType::Pawn); + Bitboard bb2 = bb; + for (PieceId id : pos.get_piece_mask(color, PieceType::Knight)) { + eval += KNIGHT_MOBILITY[pos.mobility_of(color, id, ~bb)]; + } + for (PieceId id : pos.get_piece_mask(color, PieceType::Bishop)) { + eval += BISHOP_MOBILITY[pos.mobility_of(color, id, ~bb)]; + Square sq = pos.piece_list_sq(color)[id]; + eval += BISHOP_PAWNS[std::min( + static_cast(8), + (own_pawns & Bitboard::squares_of_color(sq.color())) + .popcount()) // Weird non standard positions which can have more than 8 pawns + ] * (!pos.is_square_attacked_by(sq, color, PieceType::Pawn) + (blocked_pawns & Bitboard::central_files()).ipopcount()); - } - bb2 |= pos.attacked_by(opp, PieceType::Knight) | pos.attacked_by(opp, PieceType::Bishop); - for (PieceId id : pos.get_piece_mask(color, PieceType::Rook)) { - eval += ROOK_MOBILITY[pos.mobility_of(color, id, ~bb)]; - eval += ROOK_MOBILITY[pos.mobility_of(color, id, ~bb2)]; - // Rook lineups - Bitboard rook_file = Bitboard::file_mask(pos.piece_list_sq(color)[id].file()); - eval += ROOK_LINEUP - * (rook_file - & (pos.bitboard_for(~color, PieceType::Queen) - | pos.bitboard_for(color, PieceType::Queen))) - .ipopcount(); - } - bb2 |= pos.attacked_by(opp, PieceType::Rook); - for (PieceId id : pos.get_piece_mask(color, PieceType::Queen)) { - eval += QUEEN_MOBILITY[pos.mobility_of(color, id, ~bb)]; - eval += QUEEN_MOBILITY[pos.mobility_of(color, id, ~bb2)]; - } - if (pos.piece_count(color, PieceType::Bishop) >= 2) { - eval += BISHOP_PAIR_VAL; - } + } + bb2 |= pos.attacked_by(opp, PieceType::Knight) | pos.attacked_by(opp, PieceType::Bishop); + for (PieceId id : pos.get_piece_mask(color, PieceType::Rook)) { + eval += ROOK_MOBILITY[pos.mobility_of(color, id, ~bb)]; + eval += ROOK_MOBILITY[pos.mobility_of(color, id, ~bb2)]; + // Rook lineups + Bitboard rook_file = Bitboard::file_mask(pos.piece_list_sq(color)[id].file()); + eval += ROOK_LINEUP + * (rook_file + & (pos.bitboard_for(~color, PieceType::Queen) + | pos.bitboard_for(color, PieceType::Queen))) + .ipopcount(); + } + bb2 |= pos.attacked_by(opp, PieceType::Rook); + for (PieceId id : pos.get_piece_mask(color, PieceType::Queen)) { + eval += QUEEN_MOBILITY[pos.mobility_of(color, id, ~bb)]; + eval += QUEEN_MOBILITY[pos.mobility_of(color, id, ~bb2)]; + } + if (pos.piece_count(color, PieceType::Bishop) >= 2) { + eval += BISHOP_PAIR_VAL; } eval += KING_MOBILITY[pos.mobility_of(color, PieceId::king(), ~bb)]; @@ -418,7 +415,9 @@ PScore king_safety_activation(const Position& pos, PScore& king_safety_score) { return activated; } -PScore apply_winnable(const Position& pos, PScore& score, bool is_pawn_endgame) { +PScore apply_winnable(const Position& pos, PScore& score, u32 phase) { + + bool pawn_endgame = phase == 0; Bitboard white_pawns = pos.bitboard_for(Color::White, PieceType::Pawn); Bitboard black_pawns = pos.bitboard_for(Color::Black, PieceType::Pawn); @@ -433,7 +432,8 @@ PScore apply_winnable(const Position& pos, PScore& score, bool is_pawn_endgame) Score symmetry = WINNABLE_SYM * sym_files + WINNABLE_ASYM * asym_files; - Score winnable = WINNABLE_PAWNS * pawn_count + symmetry + WINNABLE_BIAS; + Score winnable = + WINNABLE_PAWNS * pawn_count + symmetry + WINNABLE_PAWN_ENDGAME * pawn_endgame + WINNABLE_BIAS; if (score.eg() < 0) { winnable = -winnable; @@ -455,31 +455,26 @@ Score evaluate_white_pov(const Position& pos, const PsqtState& psqt_state) { * (pos.piece_count(Color::White, PieceType::Queen) + pos.piece_count(Color::Black, PieceType::Queen)); - // TODO: replace this with endgame routing - bool pawn_endgame = phase == 0; + phase = std::min(phase, 24); PScore eval = psqt_state.score(); // Used for linear components // pawn eval eval += evaluate_pawns(pos) - evaluate_pawns(pos); - eval += evaluate_potential_checkers(pos) - - evaluate_potential_checkers(pos); - - eval += evaluate_pieces(pos, pawn_endgame) - - evaluate_pieces(pos, pawn_endgame); - - if (!pawn_endgame) { - - phase = std::min(phase, 24); + // pieces & space + eval += evaluate_pieces(pos) - evaluate_pieces(pos); + eval += evaluate_outposts(pos) - evaluate_outposts(pos); + eval += evaluate_space(pos) - evaluate_space(pos); + // Threats + eval += evaluate_threats(pos) - evaluate_threats(pos); + eval += + evaluate_pawn_push_threats(pos) - evaluate_pawn_push_threats(pos); - eval += evaluate_pawn_push_threats(pos) - - evaluate_pawn_push_threats(pos); - eval += evaluate_threats(pos) - evaluate_threats(pos); - eval += evaluate_space(pos) - evaluate_space(pos); - eval += evaluate_outposts(pos) - evaluate_outposts(pos); - } + // King safety + eval += evaluate_potential_checkers(pos) + - evaluate_potential_checkers(pos); // Nonlinear king safety components PScore white_king_attack_total = evaluate_king_safety(pos); @@ -492,7 +487,7 @@ Score evaluate_white_pov(const Position& pos, const PsqtState& psqt_state) { eval += (us == Color::White) ? TEMPO_VAL : -TEMPO_VAL; // Winnable - eval = apply_winnable(pos, eval, pawn_endgame); + eval = apply_winnable(pos, eval, phase); return static_cast(eval.phase<24>(static_cast(phase))); };