diff --git a/src/eval_constants.hpp b/src/eval_constants.hpp index c42a8365..8ee54738 100644 --- a/src/eval_constants.hpp +++ b/src/eval_constants.hpp @@ -5,180 +5,183 @@ namespace Clockwork { // clang-format off -inline const PParam PAWN_MAT = S(164, 157); -inline const PParam KNIGHT_MAT = S(569, 307); -inline const PParam BISHOP_MAT = S(518, 268); -inline const PParam ROOK_MAT = S(546, 381); -inline const PParam QUEEN_MAT = S(1115, 519); -inline const PParam TEMPO_VAL = S(65, 14); +inline const PParam PAWN_MAT = S(178, 136); +inline const PParam KNIGHT_MAT = S(720, 311); +inline const PParam BISHOP_MAT = S(766, 318); +inline const PParam ROOK_MAT = S(667, 346); +inline const PParam QUEEN_MAT = S(2146, -863); +inline const PParam TEMPO_VAL = S(65, 12); -inline const PParam BISHOP_PAIR_VAL = S(78, 156); -inline const PParam ROOK_OPEN_VAL = S(112, -26); -inline const PParam ROOK_SEMIOPEN_VAL = S(41, 19); +inline const PParam BISHOP_PAIR_VAL = S(80, 143); +inline const PParam ROOK_OPEN_VAL = S(109, -23); +inline const PParam ROOK_SEMIOPEN_VAL = S(43, 9); -inline const PParam DOUBLED_PAWN_VAL = S(-19, -84); +inline const PParam DOUBLED_PAWN_VAL = S(-34, -60); -inline const PParam POTENTIAL_CHECKER_VAL = S(-68, -11); -inline const PParam OUTPOST_KNIGHT_VAL = S(49, 43); -inline const PParam OUTPOST_BISHOP_VAL = S(59, 28); +inline const PParam POTENTIAL_CHECKER_VAL = S(-63, -3); +inline const PParam OUTPOST_KNIGHT_VAL = S(46, 47); +inline const PParam OUTPOST_BISHOP_VAL = S(56, 28); -inline const PParam PAWN_PUSH_THREAT_KNIGHT = S(51, 4); -inline const PParam PAWN_PUSH_THREAT_BISHOP = S(60, -25); -inline const PParam PAWN_PUSH_THREAT_ROOK = S(37, 37); -inline const PParam PAWN_PUSH_THREAT_QUEEN = S(68, -48); +inline const PParam PAWN_PUSH_THREAT_KNIGHT = S(46, 9); +inline const PParam PAWN_PUSH_THREAT_BISHOP = S(57, -22); +inline const PParam PAWN_PUSH_THREAT_ROOK = S(34, 44); +inline const PParam PAWN_PUSH_THREAT_QUEEN = S(70, -60); inline const std::array PAWN_PHALANX = { - S(19, 13), S(56, 34), S(73, 66), S(161, 155), S(484, 185), S(659, 637), + S(20, 21), S(52, 35), S(71, 64), S(173, 139), S(498, 162), S(659, 571), }; inline const std::array DEFENDED_PAWN = { - S(68, 40), S(58, 35), S(73, 65), S(165, 118), S(583, -19), + S(67, 42), S(57, 33), S(73, 61), S(164, 117), S(565, -7), }; inline const std::array PASSED_PAWN = { - S(-87, -99), S(-84, -77), S(-57, 3), S(17, 79), S(121, 204), S(315, 275), + S(-91, -98), S(-83, -79), S(-49, 0), S(19, 82), S(119, 194), S(334, 251), }; inline const std::array DEFENDED_PASSED_PUSH = { - S(44, -36), S(36, -6), S(29, 17), S(25, 65), S(94, 133), S(178, 229), + S(33, -32), S(33, -6), S(26, 22), S(18, 75), S(80, 144), S(160, 234), }; inline const std::array BLOCKED_PASSED_PAWN = { - S(15, -34), S(2, 3), S(3, -21), S(-4, -41), S(-21, -88), S(-286, -100), + S(17, -29), S(3, 11), S(-2, -14), S(-10, -35), S(-25, -87), S(-265, -123), }; inline const std::array FRIENDLY_KING_PASSED_PAWN_DISTANCE = { - S(0, 0), S(11, 113), S(-7, 89), S(-7, 35), S(-3, 6), S(3, 4), S(41, -0), S(15, -11), + S(0, 0), S(33, 81), S(2, 80), S(-8, 39), S(-10, 17), S(-9, 18), S(24, 16), S(2, -4), }; inline const std::array ENEMY_KING_PASSED_PAWN_DISTANCE = { - S(0, 0), S(-313, -11), S(-28, 18), S(-9, 50), S(33, 64), S(39, 83), S(48, 89), S(23, 83), + S(0, 0), S(-305, -42), S(-13, -1), S(-6, 35), S(20, 74), S(33, 92), S(45, 101), S(23, 91), }; inline const std::array KNIGHT_MOBILITY = { - S(15, -114), S(105, 56), S(151, 130), S(184, 165), S(231, 175), S(261, 208), S(297, 202), S(335, 205), S(383, 144), + S(91, -101), S(180, 69), S(224, 148), S(258, 186), S(302, 201), S(329, 237), S(363, 234), S(398, 239), S(446, 178), }; inline const std::array BISHOP_MOBILITY = { - S(1, -182), S(58, 13), S(122, 72), S(155, 115), S(181, 147), S(200, 168), S(209, 184), S(226, 190), S(237, 202), S(259, 191), S(278, 183), S(331, 144), S(343, 141), S(407, 95), + S(112, -145), S(167, 60), S(232, 128), S(264, 174), S(291, 208), S(309, 230), S(318, 249), S(333, 257), S(345, 269), S(365, 258), S(382, 251), S(432, 212), S(438, 212), S(497, 163), }; inline const std::array ROOK_MOBILITY = { - S(273, 75), S(204, 248), S(231, 267), S(252, 272), S(266, 284), S(272, 295), S(280, 304), S(290, 303), S(298, 309), S(310, 309), S(325, 307), S(336, 305), S(346, 303), S(362, 287), S(458, 198), + S(341, 106), S(287, 272), S(315, 295), S(334, 304), S(346, 319), S(353, 330), S(360, 341), S(370, 342), S(377, 350), S(388, 351), S(401, 350), S(411, 349), S(419, 347), S(438, 329), S(541, 240), }; inline const std::array QUEEN_MOBILITY = { - S(446, 24), S(555, 118), S(588, 213), S(610, 329), S(625, 386), S(637, 430), S(644, 466), S(653, 474), S(657, 500), S(663, 510), S(668, 519), S(675, 521), S(684, 515), S(688, 518), S(693, 512), S(696, 508), S(699, 504), S(703, 499), S(711, 485), S(726, 470), S(742, 446), S(769, 414), S(803, 379), S(895, 288), S(950, 236), S(1001, 204), S(1021, 178), S(977, 191), + S(699, -223), S(812, -148), S(845, -52), S(867, 65), S(882, 123), S(895, 165), S(902, 199), S(912, 205), S(917, 228), S(923, 236), S(929, 245), S(935, 247), S(944, 240), S(947, 245), S(952, 240), S(953, 238), S(955, 234), S(959, 229), S(966, 215), S(981, 198), S(997, 173), S(1024, 140), S(1058, 103), S(1155, 4), S(1199, -43), S(1262, -85), S(1296, -120), S(1232, -100), }; inline const std::array KING_MOBILITY = { - S(592, -221), S(143, -113), S(56, -38), S(41, -10), S(17, -9), S(-17, 4), S(-39, 25), S(-72, 42), S(-97, 21), + S(558, -139), S(126, -70), S(39, 8), S(26, 26), S(4, 12), S(-21, 6), S(-22, 0), S(-40, -3), S(-43, -47), }; inline const std::array KNIGHT_KING_RING = { - S(229, 227), S(373, 169), S(500, 91), + S(-7, 32), S(20, 38), S(30, 40), }; inline const std::array BISHOP_KING_RING = { - S(428, 349), S(264, 220), S(153, 63), + S(-4, 35), S(-6, 17), S(-9, -1), }; inline const std::array ROOK_KING_RING = { - S(322, 315), S(453, 307), S(503, 307), S(626, 345), S(797, 295), + S(-5, 43), S(16, 56), S(16, 63), S(23, 78), S(399, 63), }; inline const std::array QUEEN_KING_RING = { - S(913, 724), S(610, 592), S(337, 440), S(127, 235), S(55, -38), S(-10, -328), + S(438, 551), S(299, 327), S(162, 173), S(29, 70), S(-94, 59), S(-232, 48), }; inline const std::array PT_INNER_RING_ATTACKS = { - S(-91, 42), S(51, -34), S(-207, -121), S(74, 27), S(-257, -154), + S(13, 4), S(1, -2), S(19, 20), S(-4, -11), S(137, 183), }; inline const std::array PT_OUTER_RING_ATTACKS = { - S(-26, 20), S(-21, 18), S(-20, 16), S(-16, 9), S(-22, -12), + S(2, 2), S(8, 1), S(7, -0), S(6, 0), S(7, 265), }; -inline const PParam PAWN_THREAT_KNIGHT = S(243, 66); -inline const PParam PAWN_THREAT_BISHOP = S(218, 117); -inline const PParam PAWN_THREAT_ROOK = S(215, 86); -inline const PParam PAWN_THREAT_QUEEN = S(190, -47); +inline const PParam PAWN_THREAT_KNIGHT = S(240, 69); +inline const PParam PAWN_THREAT_BISHOP = S(215, 116); +inline const PParam PAWN_THREAT_ROOK = S(216, 97); +inline const PParam PAWN_THREAT_QUEEN = S(191, -54); -inline const PParam KNIGHT_THREAT_BISHOP = S(124, 73); -inline const PParam KNIGHT_THREAT_ROOK = S(256, 18); -inline const PParam KNIGHT_THREAT_QUEEN = S(168, -38); +inline const PParam KNIGHT_THREAT_BISHOP = S(123, 78); +inline const PParam KNIGHT_THREAT_ROOK = S(255, 22); +inline const PParam KNIGHT_THREAT_QUEEN = S(169, -47); -inline const PParam BISHOP_THREAT_KNIGHT = S(121, 38); -inline const PParam BISHOP_THREAT_ROOK = S(248, 72); -inline const PParam BISHOP_THREAT_QUEEN = S(206, 47); +inline const PParam BISHOP_THREAT_KNIGHT = S(117, 51); +inline const PParam BISHOP_THREAT_ROOK = S(247, 80); +inline const PParam BISHOP_THREAT_QUEEN = S(204, 52); inline const std::array BISHOP_PAWNS = { - S(4, -22), S(-3, -9), S(-5, -18), S(-11, -25), S(-17, -31), S(-23, -35), S(-26, -44), S(-32, -44), S(-45, -41), + S(3, -22), S(-4, -11), S(-5, -21), S(-10, -28), S(-16, -32), S(-22, -34), S(-26, -43), S(-33, -41), S(-45, -41), }; -inline const PParam ROOK_LINEUP = S(16, 65); +inline const PParam ROOK_LINEUP = S(13, 79); inline const std::array PAWN_PSQT = { - S(329, 291), S(197, 364), S(284, 327), S(321, 222), S(353, 168), S(282, 227), S(219, 266), S(315, 219), // - S(118, 188), S(164, 232), S(183, 183), S(160, 102), S(146, 83), S(131, 113), S(117, 154), S(67, 172), // - S(97, 154), S(103, 166), S(106, 140), S(108, 85), S(101, 74), S(73, 105), S(49, 139), S(28, 158), // - S(69, 113), S(87, 142), S(82, 129), S(83, 81), S(65, 76), S(55, 101), S(16, 139), S(-2, 129), // - S(57, 89), S(109, 104), S(86, 149), S(83, 101), S(57, 99), S(33, 103), S(19, 118), S(-6, 111), // - S(93, 88), S(182, 90), S(101, 132), S(119, 119), S(90, 115), S(73, 98), S(52, 124), S(14, 125), // + S(347, 247), S(227, 318), S(352, 291), S(316, 229), S(338, 184), S(271, 244), S(212, 272), S(307, 222), // + S(146, 157), S(208, 180), S(217, 128), S(187, 93), S(166, 79), S(146, 113), S(135, 150), S(79, 165), // + S(105, 133), S(110, 133), S(132, 82), S(122, 70), S(109, 68), S(83, 93), S(51, 136), S(33, 151), // + S(70, 105), S(82, 123), S(96, 84), S(84, 82), S(61, 85), S(50, 103), S(9, 145), S(-5, 128), // + S(61, 79), S(121, 80), S(95, 103), S(79, 103), S(49, 108), S(27, 110), S(11, 129), S(-9, 111), // + S(81, 82), S(190, 91), S(166, 134), S(112, 132), S(80, 129), S(59, 123), S(45, 137), S(11, 128), // }; inline const std::array KNIGHT_PSQT = { - S(-325, -12), S(-217, 174), S(-314, 245), S(54, 138), S(-5, 133), S(-137, 130), S(-316, 172), S(-381, 64), // - S(76, 113), S(143, 110), S(220, 75), S(208, 101), S(191, 118), S(134, 105), S(97, 124), S(60, 100), // - S(164, 85), S(190, 119), S(227, 139), S(201, 146), S(168, 158), S(123, 161), S(132, 109), S(92, 107), // - S(216, 114), S(217, 136), S(220, 157), S(200, 185), S(214, 180), S(170, 168), S(173, 131), S(159, 108), // - S(222, 105), S(251, 97), S(232, 137), S(223, 156), S(204, 158), S(200, 143), S(192, 102), S(162, 102), // - S(156, 86), S(187, 81), S(177, 116), S(191, 139), S(191, 135), S(148, 123), S(141, 87), S(107, 67), // - S(168, 71), S(188, 70), S(160, 79), S(167, 99), S(157, 99), S(126, 67), S(123, 76), S(88, 18), // - S(99, 58), S(146, 110), S(166, 67), S(181, 64), S(165, 80), S(127, 61), S(113, 88), S(61, 35), // + S(-300, -6), S(-205, 220), S(-271, 219), S(48, 175), S(-11, 171), S(-134, 172), S(-312, 228), S(-356, 67), // + S(85, 156), S(155, 145), S(233, 98), S(219, 118), S(204, 136), S(154, 129), S(116, 160), S(72, 152), // + S(182, 119), S(228, 126), S(247, 150), S(234, 148), S(203, 162), S(152, 176), S(160, 135), S(112, 147), // + S(245, 139), S(267, 140), S(260, 159), S(252, 179), S(254, 186), S(208, 180), S(206, 156), S(186, 142), // + S(246, 134), S(278, 116), S(261, 150), S(256, 165), S(233, 174), S(227, 166), S(217, 133), S(185, 137), // + S(183, 110), S(215, 108), S(206, 139), S(220, 159), S(217, 157), S(176, 143), S(166, 113), S(131, 92), // + S(194, 114), S(216, 112), S(192, 107), S(196, 126), S(185, 125), S(153, 90), S(147, 111), S(111, 54), // + S(127, 84), S(173, 123), S(192, 108), S(207, 103), S(191, 113), S(152, 92), S(139, 111), S(91, 48), // }; inline const std::array BISHOP_PSQT = { - S(-60, 187), S(-80, 177), S(-332, 223), S(-232, 200), S(-218, 219), S(-287, 233), S(-146, 226), S(-39, 193), // - S(73, 102), S(34, 160), S(51, 133), S(-12, 169), S(-7, 170), S(34, 154), S(70, 140), S(41, 126), // - S(125, 123), S(153, 131), S(155, 145), S(132, 135), S(101, 135), S(112, 135), S(132, 126), S(106, 107), // - S(118, 104), S(143, 122), S(151, 139), S(145, 169), S(179, 151), S(108, 138), S(116, 109), S(77, 109), // - S(135, 73), S(159, 99), S(164, 122), S(166, 143), S(148, 150), S(124, 138), S(91, 116), S(83, 84), // - S(161, 77), S(200, 83), S(215, 103), S(160, 135), S(152, 118), S(148, 121), S(154, 97), S(94, 103), // - S(136, 38), S(229, 50), S(189, 65), S(159, 88), S(138, 96), S(140, 71), S(138, 72), S(128, 60), // - S(154, 60), S(141, 85), S(154, 101), S(163, 65), S(161, 68), S(158, 115), S(151, 91), S(132, 83), // + S(8, 254), S(-8, 247), S(-262, 292), S(-168, 271), S(-151, 286), S(-213, 298), S(-72, 294), S(31, 259), // + S(147, 173), S(104, 229), S(123, 200), S(60, 230), S(63, 234), S(108, 223), S(143, 211), S(116, 206), // + S(222, 180), S(239, 190), S(236, 204), S(207, 198), S(177, 200), S(189, 201), S(212, 197), S(187, 181), // + S(196, 171), S(229, 182), S(229, 196), S(230, 225), S(259, 211), S(187, 200), S(197, 178), S(154, 184), // + S(219, 134), S(241, 157), S(249, 181), S(254, 197), S(233, 209), S(212, 200), S(173, 183), S(167, 152), // + S(246, 134), S(285, 146), S(299, 165), S(248, 192), S(238, 178), S(232, 182), S(239, 161), S(178, 166), // + S(223, 106), S(314, 114), S(276, 131), S(244, 152), S(224, 155), S(226, 131), S(223, 129), S(216, 120), // + S(243, 117), S(230, 142), S(237, 158), S(248, 136), S(244, 136), S(244, 169), S(237, 149), S(222, 138), // }; inline const std::array ROOK_PSQT = { - S(415, 239), S(454, 240), S(414, 262), S(430, 247), S(423, 240), S(388, 248), S(380, 258), S(369, 267), // - S(294, 301), S(385, 282), S(457, 262), S(397, 281), S(386, 286), S(365, 287), S(296, 313), S(273, 319), // - S(283, 288), S(403, 254), S(445, 247), S(422, 243), S(385, 259), S(340, 281), S(336, 279), S(261, 316), // - S(268, 273), S(352, 270), S(384, 259), S(363, 258), S(358, 262), S(314, 283), S(302, 281), S(231, 303), // - S(233, 233), S(296, 241), S(293, 254), S(269, 256), S(256, 265), S(245, 281), S(215, 275), S(195, 274), // - S(208, 196), S(270, 203), S(267, 223), S(252, 220), S(248, 219), S(223, 245), S(212, 230), S(177, 239), // - S(116, 213), S(232, 159), S(249, 180), S(249, 191), S(238, 195), S(228, 205), S(210, 189), S(179, 207), // - S(166, 208), S(189, 221), S(252, 187), S(267, 179), S(257, 188), S(239, 206), S(225, 204), S(204, 222), // + S(457, 303), S(506, 300), S(458, 321), S(465, 307), S(466, 297), S(436, 304), S(431, 315), S(413, 329), // + S(357, 350), S(448, 332), S(511, 314), S(450, 333), S(444, 335), S(426, 337), S(359, 364), S(338, 371), // + S(338, 344), S(458, 307), S(491, 301), S(472, 299), S(441, 312), S(395, 335), S(395, 334), S(322, 372), // + S(327, 329), S(415, 320), S(446, 308), S(430, 309), S(421, 316), S(377, 340), S(364, 340), S(295, 363), // + S(295, 288), S(364, 290), S(359, 308), S(340, 308), S(323, 322), S(310, 341), S(281, 337), S(260, 334), // + S(276, 245), S(341, 254), S(335, 279), S(323, 275), S(317, 276), S(289, 303), S(279, 289), S(243, 297), // + S(184, 258), S(306, 212), S(323, 235), S(322, 246), S(311, 248), S(296, 258), S(277, 244), S(246, 258), // + S(236, 242), S(262, 255), S(321, 245), S(336, 237), S(325, 243), S(307, 256), S(293, 252), S(272, 269), // }; inline const std::array QUEEN_PSQT = { - S(499, 367), S(550, 336), S(505, 391), S(444, 467), S(450, 437), S(458, 420), S(494, 354), S(421, 419), // - S(487, 427), S(463, 501), S(448, 525), S(297, 608), S(304, 596), S(378, 550), S(414, 461), S(420, 444), // - S(437, 475), S(515, 460), S(449, 535), S(412, 551), S(381, 550), S(397, 512), S(452, 429), S(439, 397), // - S(505, 379), S(514, 436), S(465, 490), S(451, 526), S(443, 527), S(434, 473), S(477, 397), S(460, 377), // - S(499, 369), S(507, 398), S(480, 449), S(445, 496), S(445, 494), S(445, 456), S(454, 401), S(470, 336), // - S(479, 304), S(516, 337), S(514, 396), S(475, 396), S(473, 391), S(475, 407), S(482, 345), S(459, 332), // - S(457, 188), S(493, 168), S(498, 240), S(510, 281), S(496, 312), S(493, 282), S(460, 328), S(461, 320), // - S(424, 211), S(458, 54), S(481, 64), S(503, 155), S(505, 222), S(501, 184), S(489, 217), S(447, 271), // + S(642, 236), S(690, 207), S(661, 252), S(617, 329), S(627, 296), S(619, 288), S(644, 220), S(571, 285), // + S(641, 287), S(613, 367), S(600, 403), S(464, 486), S(472, 474), S(530, 430), S(565, 332), S(574, 305), // + S(615, 317), S(676, 328), S(615, 407), S(567, 434), S(539, 429), S(565, 388), S(615, 294), S(609, 249), // + S(656, 257), S(673, 312), S(614, 381), S(600, 429), S(585, 432), S(584, 361), S(633, 274), S(617, 244), // + S(656, 247), S(660, 285), S(632, 346), S(598, 399), S(596, 394), S(598, 344), S(609, 278), S(627, 212), // + S(632, 200), S(668, 236), S(667, 292), S(634, 293), S(626, 291), S(628, 300), S(635, 231), S(614, 205), // + S(612, 97), S(643, 94), S(653, 146), S(667, 181), S(653, 209), S(646, 182), S(615, 214), S(621, 188), // + S(585, 102), S(616, -33), S(638, -35), S(657, 58), S(659, 122), S(655, 81), S(645, 102), S(606, 143), // }; inline const std::array KING_PSQT = { - S(-419, -256), S(56, 95), S(118, 30), S(-189, 41), S(0, 0), S(0, 0), S(0, 0), S(0, 0), // - S(123, -93), S(233, 71), S(177, 59), S(83, 0), S(0, 0), S(0, 0), S(0, 0), S(0, 0), // - S(39, 45), S(271, 49), S(240, 34), S(100, 4), S(0, 0), S(0, 0), S(0, 0), S(0, 0), // - S(-153, 47), S(182, 27), S(83, 26), S(-1, 33), S(0, 0), S(0, 0), S(0, 0), S(0, 0), // - S(-204, 31), S(95, 6), S(84, -5), S(-54, 44), S(0, 0), S(0, 0), S(0, 0), S(0, 0), // - S(-93, 16), S(169, -18), S(119, -10), S(42, 15), S(0, 0), S(0, 0), S(0, 0), S(0, 0), // - S(5, -15), S(136, -11), S(83, -13), S(4, 10), S(0, 0), S(0, 0), S(0, 0), S(0, 0), // - S(-132, -37), S(-13, -6), S(-86, -14), S(-110, -42), S(0, 0), S(0, 0), S(0, 0), S(0, 0), // + S(-346, -254), S(144, 88), S(131, 36), S(-166, 25), S(0, 0), S(0, 0), S(0, 0), S(0, 0), // + S(175, -89), S(281, 118), S(153, 126), S(75, 55), S(0, 0), S(0, 0), S(0, 0), S(0, 0), // + S(110, 27), S(321, 95), S(229, 99), S(100, 64), S(0, 0), S(0, 0), S(0, 0), S(0, 0), // + S(-79, 24), S(217, 79), S(64, 99), S(-4, 98), S(0, 0), S(0, 0), S(0, 0), S(0, 0), // + S(-141, 9), S(121, 57), S(44, 81), S(-72, 122), S(0, 0), S(0, 0), S(0, 0), S(0, 0), // + S(-65, -17), S(163, 19), S(52, 57), S(3, 83), S(0, 0), S(0, 0), S(0, 0), S(0, 0), // + S(18, -62), S(112, 9), S(24, 27), S(-35, 48), S(0, 0), S(0, 0), S(0, 0), S(0, 0), // + S(-102, -121), S(10, -57), S(-82, -62), S(-92, -98), S(0, 0), S(0, 0), S(0, 0), S(0, 0), // }; inline const std::array, 4> KING_SHELTER = {{ - {{ S(-62, 31), S(2, -37), S(49, -42), S(28, -22), S(32, -24), S(52, -45), S(7, -45), }}, - {{ S(-64, 30), S(56, -24), S(66, -48), S(13, 0), S(14, -10), S(68, -60), S(56, -37), }}, - {{ S(-52, 27), S(57, -17), S(-9, -31), S(-11, -6), S(-9, -13), S(-7, -39), S(59, -24), }}, - {{ S(-47, 12), S(16, 27), S(8, 9), S(3, 12), S(12, 4), S(17, -2), S(15, 9), }}, + {{ S(-44, -32), S(-59, -32), S(-67, -33), S(-59, -34), S(-59, -34), S(-65, -33), S(-57, -32), }}, + {{ S(-56, -35), S(-83, -36), S(-81, -38), S(-72, -41), S(-71, -39), S(-80, -37), S(-81, -35), }}, + {{ S(-72, -47), S(-83, -46), S(-82, -49), S(-78, -52), S(-78, -51), S(-80, -49), S(-81, -46), }}, + {{ S(-56, -34), S(-76, -40), S(-67, -40), S(-63, -39), S(-64, -39), S(-68, -40), S(-72, -38), }}, }}; inline const std::array BLOCKED_SHELTER_STORM = { - S(0, 0), S(0, 0), S(-2, -90), S(45, -24), S(18, -13), S(-12, -4), S(-2, 31), + S(0, 0), S(0, 0), S(-38, -24), S(-64, -29), S(-63, -29), S(-54, -30), S(-62, -32), }; inline const std::array, 4> SHELTER_STORM = {{ - {{ S(-20, -7), S(6, -7), S(12, -8), S(4, 7), S(11, 15), S(8, -4), S(7, -7), }}, - {{ S(-39, 15), S(-19, 1), S(8, -2), S(-7, 35), S(1, 30), S(8, -3), S(-20, -1), }}, - {{ S(8, -6), S(25, -30), S(18, -11), S(4, 7), S(6, 12), S(19, -7), S(23, -31), }}, - {{ S(-0, 19), S(22, 10), S(33, 7), S(6, 1), S(5, -1), S(32, 11), S(26, 13), }}, + {{ S(-50, -30), S(-63, -29), S(-62, -29), S(-60, -29), S(-62, -30), S(-60, -29), S(-63, -29), }}, + {{ S(-49, -30), S(-59, -29), S(-67, -28), S(-62, -32), S(-63, -32), S(-65, -28), S(-59, -28), }}, + {{ S(-55, -33), S(-62, -31), S(-63, -30), S(-57, -30), S(-57, -31), S(-63, -30), S(-61, -30), }}, + {{ S(-56, -34), S(-66, -31), S(-67, -32), S(-58, -30), S(-57, -30), S(-67, -31), S(-68, -31), }}, }}; -// Epoch duration: 9.05449s +inline TunableSigmoid<32> KING_SAFETY_ACTIVATION( + 895, 2096, -126, 37 +); +// Epoch duration: 9.86598s // clang-format on } // namespace Clockwork diff --git a/src/eval_types.hpp b/src/eval_types.hpp index 6391bb8c..6a30cd93 100644 --- a/src/eval_types.hpp +++ b/src/eval_types.hpp @@ -2,6 +2,7 @@ #include "util/types.hpp" #include +#include #include #include #include @@ -107,7 +108,6 @@ class PScore { }; using PParam = PScore; - #else using Score = Autograd::ValueHandle; @@ -131,11 +131,114 @@ using PParam = Autograd::PairPlaceholder; // Handle for the TUNABLE parameter #define PSCORE_ZERO Autograd::PairHandle::create(0, 0) #else - // ... (non-tuning definitions) ... +// ... (non-tuning definitions) ... #define S(a, b) PScore((a), (b)) #define CS(a, b) PScore((a), (b)) #define PPARAM_ZERO PScore(0, 0) #define PSCORE_ZERO PScore(0, 0) #endif + +// TunableSigmoid: a * sigmoid((x + c) / b) +// a and c are tunable pairs (mg, eg), b is a constant scale parameter +// For inference: uses a lookup table with linear interpolation in the 95% range +// 95% range is approximately [-b*ln(39), b*ln(39)] = [-3.664b, 3.664b] + +template +#ifdef EVAL_TUNING +class TunableSigmoid { +private: + PParam m_a; // Scaling parameter + PParam m_c; // Offset parameter + + static constexpr f64 B = static_cast(B_SCALE); + +public: + TunableSigmoid(i32 a0, i32 a1, i32 c0, i32 c1) : + m_a(S(a0, a1)), + m_c(S(c0, c1)) { + } + + PScore operator()(PScore x) const { + auto scaled = x / B; + auto shifted = scaled + (m_c / B); + auto sig = shifted.sigmoid(); + return m_a * sig; + } + + PParam a() const { + return m_a; + } + i32 b() const { + return B_SCALE; + } + PParam c() const { + return m_c; + } +}; +#else +class TunableSigmoid { +private: + static constexpr i32 TABLE_SIZE = 256; + static constexpr i32 FP_SHIFT = 16; + static constexpr i32 FP_ONE = 1 << FP_SHIFT; + static constexpr f64 B = static_cast(B_SCALE); + static constexpr f64 LN_39 = 3.6635616461296463; + + struct Table { + i32 range_min; + i32 range_max; + i32 range_span; + i32 scale_fp; + std::array values; + }; + + Table m_mg; + Table m_eg; + +public: + TunableSigmoid(i32 a_mg, i32 a_eg, i32 c_mg, i32 c_eg) { + build_table(m_mg, a_mg, c_mg); + build_table(m_eg, a_eg, c_eg); + } + + PScore operator()(PScore x) const { + return PScore(lookup(x.mg(), m_mg), lookup(x.eg(), m_eg)); + } + +private: + static void build_table(Table& tbl, i32 a, i32 c) { + const f64 bound = B * LN_39; + tbl.range_min = static_cast(-bound) - c; + tbl.range_max = static_cast(bound) - c; + tbl.range_span = tbl.range_max - tbl.range_min; + + tbl.scale_fp = + static_cast((static_cast(TABLE_SIZE - 1) << FP_SHIFT) / tbl.range_span); + + for (i32 i = 0; i < TABLE_SIZE; ++i) { + const f64 t = static_cast(i) / (TABLE_SIZE - 1); + const f64 x = tbl.range_min + t * tbl.range_span; + const f64 z = (x + c) / B; + const f64 sig = 1.0 / (1.0 + std::exp(-z)); + + tbl.values[i] = static_cast(std::lround(a * sig)); + } + } + + static i16 lookup(i16 x_val, const Table& tbl) { + const i32 x = std::clamp(static_cast(x_val), tbl.range_min, tbl.range_max); + const i64 idx_fp = static_cast(x - tbl.range_min) * tbl.scale_fp; + + const i32 idx = static_cast(idx_fp >> FP_SHIFT); + const i32 frac = static_cast(idx_fp & (FP_ONE - 1)); + + const i32 v0 = tbl.values[idx]; + const i32 v1 = tbl.values[std::min(idx + 1, TABLE_SIZE - 1)]; + + return static_cast(v0 + ((v1 - v0) * frac >> FP_SHIFT)); + } +}; +#endif + } // namespace Clockwork diff --git a/src/evaltune_main.cpp b/src/evaltune_main.cpp index 5fc62be0..ba981f70 100644 --- a/src/evaltune_main.cpp +++ b/src/evaltune_main.cpp @@ -131,7 +131,7 @@ int main() { Parameters current_parameter_values = Graph::get().get_all_parameter_values(); // Uncomment for zero tune: Overwrite them all with zeros. - current_parameter_values = Parameters::zeros(parameter_count); + current_parameter_values = Parameters::rand_init(parameter_count); // The optimizer will now start with all-zero parameters AdamW optim(parameter_count, 10, 0.9, 0.999, 1e-8, 0.0); @@ -405,6 +405,17 @@ int main() { print_table("BLOCKED_SHELTER_STORM", BLOCKED_SHELTER_STORM); print_2d_array("SHELTER_STORM", SHELTER_STORM); + auto print_sigmoid = [](const std::string& name, const auto& sigmoid, const i32 templ) { + PairHandle a_h = static_cast(sigmoid.a()); + PairHandle c_h = static_cast(sigmoid.c()); + std::cout << "inline TunableSigmoid<" << templ << "> " << name << "(\n" + << "\t" << std::lround(a_h.first()) << ", " << std::lround(a_h.second()) + << ", " << std::lround(c_h.first()) << ", " << std::lround(c_h.second()) + << "\n" + << ")\n"; + }; + print_sigmoid("KING_SAFETY_ACTIVATION", KING_SAFETY_ACTIVATION, 32); + #endif const auto end = time::Clock::now(); std::cout << "// Epoch duration: " << time::cast(end - start).count() diff --git a/src/evaluation.cpp b/src/evaluation.cpp index 6eea0576..0e3a05af 100644 --- a/src/evaluation.cpp +++ b/src/evaluation.cpp @@ -222,10 +222,11 @@ PScore evaluate_pawn_push_threats(const Position& pos) { } template -PScore evaluate_pieces(const Position& pos) { - constexpr Color opp = ~color; - PScore eval = PSCORE_ZERO; - Bitboard own_pawns = pos.bitboard_for(color, PieceType::Pawn); +std::pair evaluate_pieces(const Position& pos) { + constexpr Color opp = ~color; + PScore eval = PSCORE_ZERO; + PScore king_safety_score = PSCORE_ZERO; + Bitboard own_pawns = pos.bitboard_for(color, PieceType::Pawn); Bitboard blocked_pawns = own_pawns & pos.board().get_occupied_bitboard().shift_relative(color, Direction::South); constexpr Bitboard early_ranks = color == Color::White @@ -237,11 +238,11 @@ PScore evaluate_pieces(const Position& pos) { Bitboard opp_king_ring = king_ring_table[pos.king_sq(opp).raw]; for (PieceId id : pos.get_piece_mask(color, PieceType::Knight)) { eval += KNIGHT_MOBILITY[pos.mobility_of(color, id, ~bb)]; - eval += KNIGHT_KING_RING[pos.mobility_of(color, id, opp_king_ring)]; + king_safety_score += KNIGHT_KING_RING[pos.mobility_of(color, id, opp_king_ring)]; } for (PieceId id : pos.get_piece_mask(color, PieceType::Bishop)) { eval += BISHOP_MOBILITY[pos.mobility_of(color, id, ~bb)]; - eval += BISHOP_KING_RING[pos.mobility_of(color, id, opp_king_ring)]; + king_safety_score += BISHOP_KING_RING[pos.mobility_of(color, id, opp_king_ring)]; Square sq = pos.piece_list_sq(color)[id]; eval += BISHOP_PAWNS[std::min( static_cast(8), @@ -255,7 +256,7 @@ PScore evaluate_pieces(const Position& pos) { 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)]; - eval += ROOK_KING_RING[pos.mobility_of(color, id, opp_king_ring)]; + king_safety_score += ROOK_KING_RING[pos.mobility_of(color, id, opp_king_ring)]; // Rook lineups Bitboard rook_file = Bitboard::file_mask(pos.piece_list_sq(color)[id].file()); eval += ROOK_LINEUP @@ -268,7 +269,7 @@ PScore evaluate_pieces(const Position& pos) { 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)]; - eval += QUEEN_KING_RING[pos.mobility_of(color, id, opp_king_ring)]; + king_safety_score += QUEEN_KING_RING[pos.mobility_of(color, id, opp_king_ring)]; } eval += KING_MOBILITY[pos.mobility_of(color, PieceId::king(), ~bb)]; @@ -276,7 +277,7 @@ PScore evaluate_pieces(const Position& pos) { eval += BISHOP_PAIR_VAL; } - return eval; + return {eval, king_safety_score}; } template @@ -406,6 +407,13 @@ PScore evaluate_space(const Position& pos) { return eval; } +template +PScore king_safety_activation(const Position& pos, PScore& king_safety_score) { + // Apply sigmoid activation to king safety score + PScore activated = KING_SAFETY_ACTIVATION(king_safety_score); + return activated; +} + Score evaluate_white_pov(const Position& pos, const PsqtState& psqt_state) { const Color us = pos.active_color(); usize phase = pos.piece_count(Color::White, PieceType::Knight) @@ -419,19 +427,32 @@ 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); + phase = std::min(phase, 24); + PScore eval = psqt_state.score(); // Used for linear components - PScore eval = psqt_state.score(); - eval += evaluate_pieces(pos) - evaluate_pieces(pos); + // Pieces - get king safety scores directly + auto [white_piece_score, white_king_attack] = evaluate_pieces(pos); + auto [black_piece_score, black_king_attack] = evaluate_pieces(pos); + eval += white_piece_score - black_piece_score; + + // Other linear components 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_king_safety(pos) - evaluate_king_safety(pos); eval += evaluate_space(pos) - evaluate_space(pos); eval += evaluate_outposts(pos) - evaluate_outposts(pos); + + // Nonlinear king safety components + PScore white_king_attack_total = white_king_attack + evaluate_king_safety(pos); + PScore black_king_attack_total = black_king_attack + evaluate_king_safety(pos); + + // Nonlinear adjustment + eval += king_safety_activation(pos, white_king_attack_total) + - king_safety_activation(pos, black_king_attack_total); + eval += (us == Color::White) ? TEMPO_VAL : -TEMPO_VAL; return static_cast(eval.phase<24>(static_cast(phase))); }; diff --git a/src/tuning/graph.cpp b/src/tuning/graph.cpp index dfa738e6..84ae7cb7 100644 --- a/src/tuning/graph.cpp +++ b/src/tuning/graph.cpp @@ -200,6 +200,53 @@ PairHandle Graph::record_pair_value(OpType op, PairHandle lhs, ValueHandle rhs) return out; } +PairHandle Graph::record_pair_unary(OpType op, PairHandle input) { + PairHandle out = m_pairs.next_handle(); + f64x2 in_val = m_pairs.val(input.index); + f64x2 res = f64x2::zero(); + + switch (op) { + case OpType::PairSigmoid: { + // Apply sigmoid to each component: 1 / (1 + exp(-x)) + f64 mg = in_val.first(); + f64 eg = in_val.second(); + f64 sig_mg = 1.0 / (1.0 + std::exp(-mg)); + f64 sig_eg = 1.0 / (1.0 + std::exp(-eg)); + res = f64x2::make(sig_mg, sig_eg); + break; + } + default: + break; + } + + m_pairs.alloc(res, f64x2::zero()); + + m_tape.push_back(Node::make_scalar(op, out.index, input.index, 0.0)); + + return out; +} + +PairHandle Graph::record_pair_value(OpType op, PairHandle lhs, PairHandle rhs) { + PairHandle out = m_pairs.next_handle(); + f64x2 l = m_pairs.val(lhs.index); + f64x2 r = m_pairs.val(rhs.index); + f64x2 res = f64x2::zero(); + + switch (op) { + case OpType::PairMulPair: + res = f64x2::mul(l, r); + break; + default: + break; + } + + m_pairs.alloc(res, f64x2::zero()); + + m_tape.push_back(Node::make_binary(op, out.index, lhs.index, rhs.index)); + + return out; +} + ValueHandle Graph::record_phase(PairHandle lhs, f64 alpha) { ValueHandle out = m_values.next_handle(); f64x2 pair_val = m_pairs.val(lhs.index); @@ -335,6 +382,25 @@ void Graph::backward() { break; } + case OpType::PairSigmoid: { + const f64x2 grad_out = pair_grads[out_idx]; + + // sigmoid output values already computed in forward pass + f64x2 sigmoid_out = pair_vals[out_idx]; + + f64 sig_mg = sigmoid_out.first(); + f64 sig_eg = sigmoid_out.second(); + + f64 grad_mg = sig_mg * (1.0 - sig_mg); + f64 grad_eg = sig_eg * (1.0 - sig_eg); + + f64x2 local_grad = f64x2::make(grad_mg, grad_eg); + f64x2 update = f64x2::mul(local_grad, grad_out); + + pair_grads[node.lhs()] = f64x2::add(pair_grads[node.lhs()], update); + break; + } + case OpType::PairAdd: { const f64x2 grad_out = pair_grads[out_idx]; pair_grads[node.lhs()] = f64x2::add(pair_grads[node.lhs()], grad_out); @@ -411,6 +477,17 @@ void Graph::backward() { grad_out.first() * recip.first() + grad_out.second() * recip.second(); break; } + case OpType::PairMulPair: { + const f64x2 grad_out = pair_grads[out_idx]; + f64x2 l = pair_vals[node.lhs()]; + f64x2 r = pair_vals[node.rhs()]; + + f64x2 grad_lhs = f64x2::mul(grad_out, r); + f64x2 grad_rhs = f64x2::mul(grad_out, l); + pair_grads[node.lhs()] = f64x2::add(pair_grads[node.lhs()], grad_lhs); + pair_grads[node.rhs()] = f64x2::add(pair_grads[node.rhs()], grad_rhs); + break; + } default: unreachable(); diff --git a/src/tuning/graph.hpp b/src/tuning/graph.hpp index 7053f47a..61f971e5 100644 --- a/src/tuning/graph.hpp +++ b/src/tuning/graph.hpp @@ -41,6 +41,8 @@ class Graph { PairHandle record_pair_op(OpType op, PairHandle lhs, PairHandle rhs); PairHandle record_pair_scalar(OpType op, PairHandle input, f64 scalar); PairHandle record_pair_value(OpType op, PairHandle pair, ValueHandle val); + PairHandle record_pair_value(OpType op, PairHandle lhs, PairHandle rhs); + PairHandle record_pair_unary(OpType op, PairHandle input); ValueHandle record_phase(PairHandle input, f64 alpha); diff --git a/src/tuning/info.hpp b/src/tuning/info.hpp index d3874d1c..79227b15 100644 --- a/src/tuning/info.hpp +++ b/src/tuning/info.hpp @@ -3,6 +3,7 @@ #include "util/types.hpp" #include "util/vec/sse2.hpp" #include +#include #include namespace Clockwork::Autograd { @@ -23,6 +24,32 @@ struct Parameters { return result; } + static Parameters ones(ParameterCountInfo counts) { + Parameters result; + result.parameters.resize(counts.parameter_count, 1.0); + result.pair_parameters.resize(counts.pair_parameter_count, f64x2::make(1.0, 1.0)); + return result; + } + + static Parameters rand_init(ParameterCountInfo counts, f64 mean = 0.0, f64 variance = 0.1) { + std::mt19937_64 rng{474747}; + std::uniform_real_distribution distr(mean, variance); + + Parameters result; + + result.parameters.resize(counts.parameter_count); + std::generate(result.parameters.begin(), result.parameters.end(), [&] { + return distr(rng); + }); + + result.pair_parameters.resize(counts.pair_parameter_count); + std::generate(result.pair_parameters.begin(), result.pair_parameters.end(), [&] { + return f64x2::make(distr(rng), distr(rng)); + }); + + return result; + } + void accumulate(const Parameters& b) { assert(b.parameters.size() == parameters.size()); assert(b.pair_parameters.size() == pair_parameters.size()); diff --git a/src/tuning/operations.hpp b/src/tuning/operations.hpp index d01dfd7d..fb162fb7 100644 --- a/src/tuning/operations.hpp +++ b/src/tuning/operations.hpp @@ -38,6 +38,7 @@ enum class OpType : u32 { PairAdd, PairSub, PairNeg, + PairSigmoid, // Pair-Scalar Ops PairMulScalar, @@ -50,6 +51,9 @@ enum class OpType : u32 { PairDivValue, ValueDivPair, + // Pair-Pair Ops + PairMulPair, + // Phasing Phase, // Pair -> Value via alpha diff --git a/src/tuning/value.cpp b/src/tuning/value.cpp index 8968b153..f2a1e43d 100644 --- a/src/tuning/value.cpp +++ b/src/tuning/value.cpp @@ -103,6 +103,10 @@ void PairHandle::zero_grad() const { ValueHandle PairHandle::phase_impl(f64 scaled_alpha) const { return Graph::get().record_phase(*this, scaled_alpha); } +// Sigmoid operation +PairHandle PairHandle::sigmoid() const { + return Graph::get().record_pair_unary(OpType::PairSigmoid, *this); +} // ValueHandle Operators ValueHandle operator-(ValueHandle a) { @@ -171,6 +175,9 @@ PairHandle operator*(PairHandle a, f64 scalar) { PairHandle operator*(f64 scalar, PairHandle a) { return a * scalar; } +PairHandle operator*(PairHandle a, PairHandle b) { + return Graph::get().record_pair_value(OpType::PairMulPair, a, b); +} PairHandle operator/(PairHandle a, f64 scalar) { return Graph::get().record_pair_scalar(OpType::PairDivScalar, a, scalar); } diff --git a/src/tuning/value.hpp b/src/tuning/value.hpp index c8d60241..4cfc244a 100644 --- a/src/tuning/value.hpp +++ b/src/tuning/value.hpp @@ -71,6 +71,8 @@ struct PairHandle { ValueHandle phase(f64 alpha) const { return phase_impl(alpha / max); } + + PairHandle sigmoid() const; }; // Operation decls @@ -99,6 +101,7 @@ PairHandle operator/(PairHandle a, f64 scalar); PairHandle operator/(f64 scalar, PairHandle a); PairHandle operator*(PairHandle a, ValueHandle v); PairHandle operator*(ValueHandle v, PairHandle a); +PairHandle operator*(PairHandle a, PairHandle b); PairHandle operator/(PairHandle a, ValueHandle v); PairHandle operator/(ValueHandle v, PairHandle a); std::ostream& operator<<(std::ostream& os, const PairHandle& p); diff --git a/src/util/static_vector.hpp b/src/util/static_vector.hpp index 6dde8c23..4c096b71 100644 --- a/src/util/static_vector.hpp +++ b/src/util/static_vector.hpp @@ -166,6 +166,16 @@ class StaticVector { m_len = new_size; } + template + void resize_with(usize new_size, F&& f) + requires std::invocable && std::constructible_from> + { + resize_with(new_size, [&](usize) { + return f(); + }); + } + + T& operator[](usize index) { assert(index < m_len); return data()[index];