diff --git a/CMakeLists.txt b/CMakeLists.txt index 0cbab5b..abaf4bb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,7 +18,7 @@ set(SOURCE_FILES pvs.h pvs.cpp syzygy/tbconfig.h syzygy/tbconfig.cpp syzygy/fathom.h syzygy/fathom.cpp) -set(TEST_FILES testing/runner.cpp testing/util.h testing/util.cpp +set(TEST_FILES testing/util.h testing/util.cpp testing/test_bb.cpp testing/test_board.cpp testing/test_perft.cpp @@ -39,7 +39,7 @@ Include(FetchContent) FetchContent_Declare( Catch2 GIT_REPOSITORY https://github.com/catchorg/Catch2.git - GIT_TAG v2.13.7 + GIT_TAG v3.4.0 ) FetchContent_Declare( Fathom @@ -53,11 +53,10 @@ include_directories(syzygy ${fathom_SOURCE_DIR}/src) list(APPEND SOURCE_FILES ${fathom_SOURCE_DIR}/src/tbprobe.c) # Enable unit tests -list(APPEND CMAKE_MODULE_PATH ${catch2_SOURCE_DIR}/contrib) include(CTest) include(Catch) add_executable(ToppleTest ${SOURCE_FILES} ${TEST_FILES}) -target_link_libraries(ToppleTest Catch2::Catch2) +target_link_libraries(ToppleTest Catch2::Catch2WithMain) target_compile_options(ToppleTest PUBLIC -march=native -O3) catch_discover_tests(ToppleTest) diff --git a/bb.cpp b/bb.cpp index a56e34f..f83ca47 100644 --- a/bb.cpp +++ b/bb.cpp @@ -222,19 +222,34 @@ namespace bb_sliders { /* * Initialisation of various utility bitboards */ -namespace bb_util { +namespace bb_tables { U64 between[64][64]; U64 line[64][64]; U64 ray[64][64]; - U64 file[8]; + U64 king_area[64]; - void init_util() { - for (uint8_t a = 0; a < 64; a++) { - // File - { - file[file_index(a)] |= single_bit(a); - } + U64 king_moves[64]; + U64 knight_moves[64]; + U64 pawn_moves_x1[2][64]; + U64 pawn_moves_x2[2][64]; + U64 pawn_caps[2][64]; + + // We use this method (and signed integers) to not generate moves off the edge of the board (or which wrap around) + inline bool valid_square(const int &file, const int &rank) { + return file >= 0 && file < 8 && rank >= 0 && rank < 8; + } + // Check if move is valid and add to lookup table if it is + inline void update_array(U64 *arr, const uint8_t &file, const uint8_t &rank, + int file_offset, int rank_offset) { + if (valid_square(file + file_offset, rank + rank_offset)) { + arr[square_index(file, rank)] |= single_bit(square_index(file + file_offset, rank + rank_offset)); + } + } + + void init_tables() { + // Utility tables + for (uint8_t a = 0; a < 64; a++) { for (uint8_t b = 0; b < 64; b++) { // Between { @@ -272,35 +287,8 @@ namespace bb_util { } } } - } -} -/** - * ===================================================================================================================== - * GENERATION FOR NON-SLIDING PIECES - * ===================================================================================================================== - */ -namespace bb_normal_moves { - U64 king_moves[64]; - U64 knight_moves[64]; - U64 pawn_moves_x1[2][64]; - U64 pawn_moves_x2[2][64]; - U64 pawn_caps[2][64]; - - // We use this method (and signed integers) to not generate moves off the edge of the board (or which wrap around) - inline bool valid_square(const int &file, const int &rank) { - return file >= 0 && file < 8 && rank >= 0 && rank < 8; - } - - // Check if move is valid and add to lookup table if it is - inline void update_array(U64 *arr, const uint8_t &file, const uint8_t &rank, - int file_offset, int rank_offset) { - if (valid_square(file + file_offset, rank + rank_offset)) { - arr[square_index(file, rank)] |= single_bit(square_index(file + file_offset, rank + rank_offset)); - } - } - - void init_normal_moves() { + // Normal moves for (uint8_t file_from = 0; file_from < 8; file_from++) { for (uint8_t rank_from = 0; rank_from < 8; rank_from++) { // King moves @@ -341,13 +329,23 @@ namespace bb_normal_moves { update_array(pawn_caps[BLACK], file_from, rank_from, -1, -1); } } + + // King area + for (int file_from = 0; file_from < 8; file_from++) { + for (int rank_from = 0; rank_from < 8; rank_from++) { + king_area[square_index(file_from, rank_from)] = king_moves[square_index(std::clamp(file_from, 1, 6), std::clamp(rank_from, 1, 6))]; + } + } } } -void init_tables() { - bb_sliders::init_sliders(); - bb_util::init_util(); - bb_normal_moves::init_normal_moves(); +namespace { + struct init_tables { + init_tables() { + bb_sliders::init_sliders(); + bb_tables::init_tables(); + } + } _; } uint8_t to_sq(char file, char rank) { diff --git a/bb.h b/bb.h index 278acb6..1dccb14 100644 --- a/bb.h +++ b/bb.h @@ -327,29 +327,18 @@ namespace bb_sliders { /* * Potentially useful bitboard lookup tables */ -namespace bb_util { +namespace bb_tables { extern U64 between[64][64]; // between[a][b] is the bitboard between a and b, or 0 if they are unaligned extern U64 line[64][64]; // line[a][b] is the bitboard of the line through a and b, or 0 if they are unaligned extern U64 ray[64][64]; // ray[a][b] is the bitboard of the ray from a through b, or 0 if they are unaligned - extern U64 file[8]; // file[f] is the bitboard of file number f -} - -/* - * Non-sliding move generation lookup tables - */ -namespace bb_normal_moves { extern U64 king_moves[64]; extern U64 knight_moves[64]; extern U64 pawn_moves_x1[2][64]; // Normal pawn advances extern U64 pawn_moves_x2[2][64]; // Double pawn advances on the 2nd or 7th rank extern U64 pawn_caps[2][64]; // Pawn captures + extern U64 king_area[64]; // 3x3 area around the king, shifted inwards if the king is on the edge of the board } -/** - * Initialise bitboard tables. Must be called before use of any other functions in this header. - */ -void init_tables(); - /** * Generate a bitboard of possible moves from the {@code square}, assuming that {@code occupied} is a bitboard which * represents the occupied square on the board. @@ -374,11 +363,11 @@ inline U64 find_moves(Team side, uint8_t square, U64 occupied); template<> inline U64 find_moves(Team side, uint8_t square, U64 occupied) { U64 result = 0; - result |= occupied & bb_normal_moves::pawn_caps[side][square]; - if (!(occupied & bb_normal_moves::pawn_moves_x1[side][square])) { - result |= bb_normal_moves::pawn_moves_x1[side][square]; - if (!(occupied & bb_normal_moves::pawn_moves_x2[side][square])) { - result |= bb_normal_moves::pawn_moves_x2[side][square]; + result |= occupied & bb_tables::pawn_caps[side][square]; + if (!(occupied & bb_tables::pawn_moves_x1[side][square])) { + result |= bb_tables::pawn_moves_x1[side][square]; + if (!(occupied & bb_tables::pawn_moves_x2[side][square])) { + result |= bb_tables::pawn_moves_x2[side][square]; } } return result; @@ -386,7 +375,7 @@ inline U64 find_moves(Team side, uint8_t square, U64 occupied) { template<> inline U64 find_moves(Team side, uint8_t square, U64 occupied) { - return bb_normal_moves::knight_moves[square]; + return bb_tables::knight_moves[square]; } template<> @@ -406,7 +395,7 @@ inline U64 find_moves(Team side, uint8_t square, U64 occupied) { template<> inline U64 find_moves(Team side, uint8_t square, U64 occupied) { - return bb_normal_moves::king_moves[square]; + return bb_tables::king_moves[square]; } /** @@ -447,7 +436,7 @@ inline U64 find_moves(Piece type, Team side, uint8_t square, U64 occupied) { * @return possible captures of the pawn */ inline U64 pawn_caps(Team side, uint8_t square) { - return bb_normal_moves::pawn_caps[side][square]; + return bb_tables::pawn_caps[side][square]; } /** @@ -470,7 +459,7 @@ inline bool multiple_bits(U64 bb) { * @return bitboard containing bits between the two squares */ inline U64 bits_between(uint8_t a, uint8_t b) { - return bb_util::between[a][b]; + return bb_tables::between[a][b]; } /** @@ -483,7 +472,7 @@ inline U64 bits_between(uint8_t a, uint8_t b) { * @return bitboard containing a line which crosses the two squares */ inline U64 line(uint8_t a, uint8_t b) { - return bb_util::line[a][b]; + return bb_tables::line[a][b]; } /** @@ -497,7 +486,19 @@ inline U64 line(uint8_t a, uint8_t b) { * @return bitboard containing the ray */ inline U64 ray(uint8_t origin, uint8_t direction) { - return bb_util::ray[origin][direction]; + return bb_tables::ray[origin][direction]; +} + +/** + * Generates a bitboard containing the area of the board immediately around the king. If the king is on the edge of + * the board, this returns a region shifted towards the centre of the board to account for the reduced mobility of + * the king, resulting in a potentially better evaluation of safety. + * + * @param sq king position + * @return bitboard of the king area + */ +inline U64 king_area(uint8_t sq) { + return bb_tables::king_area[sq]; } /** @@ -506,9 +507,18 @@ inline U64 ray(uint8_t origin, uint8_t direction) { * @param file_index index of file * @return bitboard of the file */ - -inline U64 file_mask(uint8_t file_index) { - return bb_util::file[file_index]; +constexpr U64 file_mask(uint8_t file_index) { + constexpr U64 mask[8] = { + 0x0101010101010101, + 0x0202020202020202, + 0x0404040404040404, + 0x0808080808080808, + 0x1010101010101010, + 0x2020202020202020, + 0x4040404040404040, + 0x8080808080808080, + }; + return mask[file_index]; } /** diff --git a/eval.cpp b/eval.cpp index 05dbb75..d78ff53 100644 --- a/eval.cpp +++ b/eval.cpp @@ -7,35 +7,6 @@ #include #include -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/// Utility tables -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -U64 BB_KING_SQUARE[64] = {}; -U64 BB_KING_CIRCLE[64] = {}; -U64 BB_PAWN_SHIELD[64] = {}; - -void evaluator_t::eval_init() { - for (uint8_t sq = 0; sq < 64; sq++) { - BB_KING_SQUARE[sq] = single_bit(sq) | find_moves(WHITE, sq, 0); - } - - for (uint8_t sq = 0; sq < 64; sq++) { - // King circle - BB_KING_CIRCLE[sq] = BB_KING_SQUARE[sq]; - if(rank_index(sq) == 0) BB_KING_CIRCLE[sq] |= bb_shifts::shift(BB_KING_SQUARE[sq]); - if(rank_index(sq) == 7) BB_KING_CIRCLE[sq] |= bb_shifts::shift(BB_KING_SQUARE[sq]); - if(file_index(sq) == 0) BB_KING_CIRCLE[sq] |= bb_shifts::shift(BB_KING_SQUARE[sq]); - if(file_index(sq) == 7) BB_KING_CIRCLE[sq] |= bb_shifts::shift(BB_KING_SQUARE[sq]); - - if(rank_index(sq) <= 1) { - BB_PAWN_SHIELD[sq] = bb_shifts::shift(BB_KING_SQUARE[sq]); - } else if(rank_index(sq) >= 6) { - BB_PAWN_SHIELD[sq] = bb_shifts::shift(BB_KING_SQUARE[sq]); - } - } -} - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// Preprocessing evaluation parameters //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -123,8 +94,8 @@ int evaluator_t::evaluate(const board_t &board) { // Initialise king danger evaluation data.king_pos[WHITE] = bit_scan(board.pieces(WHITE, KING)); data.king_pos[BLACK] = bit_scan(board.pieces(BLACK, KING)); - data.king_circle[WHITE] = BB_KING_CIRCLE[data.king_pos[WHITE]]; - data.king_circle[BLACK] = BB_KING_CIRCLE[data.king_pos[BLACK]]; + data.king_circle[WHITE] = king_area(data.king_pos[WHITE]); + data.king_circle[BLACK] = king_area(data.king_pos[BLACK]); data.king_danger[WHITE] = params.kat_zero; data.king_danger[BLACK] = params.kat_zero; data.update_attacks(WHITE, KING, find_moves(WHITE, data.king_pos[WHITE], board.all())); @@ -296,8 +267,8 @@ v4si_t evaluator_t::eval_pawns(const board_t &board, eval_data_t &data, float &t }; // King shield - int pawn_shield_w = std::min(3, pop_count(BB_PAWN_SHIELD[data.king_pos[WHITE]] & board.pieces(WHITE, PAWN))); - int pawn_shield_b = std::min(3, pop_count(BB_PAWN_SHIELD[data.king_pos[BLACK]] & board.pieces(BLACK, PAWN))); + int pawn_shield_w = std::min(3, pop_count(data.king_circle[WHITE] & board.pieces(WHITE, PAWN))); + int pawn_shield_b = std::min(3, pop_count(data.king_circle[BLACK] & board.pieces(BLACK, PAWN))); score += (blocked_count[WHITE][0] - blocked_count[BLACK][0]) * params.blocked[0]; score += (blocked_count[WHITE][1] - blocked_count[BLACK][1]) * params.blocked[1]; diff --git a/eval.h b/eval.h index 3a3e67b..5e19f08 100644 --- a/eval.h +++ b/eval.h @@ -11,17 +11,16 @@ #include "board.h" #include "pawns.h" -// lq: 0.0633654 +// ql: 0.0612082 struct eval_params_t { // Tapering parameters - int mat_exch_knight = 24; - int mat_exch_bishop = 32; - int mat_exch_rook = 55; - int mat_exch_queen = 155; - int pt_blocked_file[4] = {65, 71, 117, 118,}; - int pt_open_file[4] = {24, -37, -32, -40,}; - int pt_island = 20; - int pt_max = 499; + int mat_exch_knight = 19; + int mat_exch_bishop = 35; + int mat_exch_rook = 69; + int mat_exch_queen = 141; + int pt_blocked_file[4] = {64,82,78,81,}; + int pt_closed_file[4] = {33,33,51,46,}; + int pt_max = 480; // Piece-square tables // 4x4 tables include the following squares, mirrored horizontally and vertically @@ -30,204 +29,64 @@ struct eval_params_t { // A2, B2, C2, D2, // A1, B1, C1, D1, // Pawn tables are mirrored vertically only - v4si_t n_pst[16] = {{430, 391, 423, 377}, - {424, 416, 419, 376}, - {438, 422, 439, 382}, - {467, 418, 460, 388}, - {394, 380, 437, 370}, - {410, 405, 418, 376}, - {418, 414, 403, 385}, - {432, 418, 434, 387}, - {408, 378, 435, 357}, - {403, 377, 438, 374}, - {409, 385, 419, 383}, - {419, 410, 421, 380}, - {378, 230, 360, 324}, - {391, 362, 454, 360}, - {391, 378, 432, 360}, - {394, 378, 433, 379},}; - v4si_t q_pst[16] = {{1323, 1321, 1275, 1276}, - {1333, 1315, 1318, 1290}, - {1316, 1314, 1292, 1288}, - {1327, 1308, 1320, 1306}, - {1323, 1335, 1307, 1232}, - {1319, 1329, 1307, 1265}, - {1320, 1325, 1281, 1288}, - {1328, 1311, 1254, 1295}, - {1326, 1335, 1226, 1243}, - {1310, 1316, 1260, 1270}, - {1320, 1327, 1277, 1256}, - {1327, 1331, 1263, 1268}, - {1316, 1326, 1255, 1209}, - {1316, 1316, 1236, 1250}, - {1323, 1310, 1250, 1253}, - {1328, 1327, 1244, 1243},}; - v4si_t b_pst[16] = {{394, 415, 409, 393}, - {414, 401, 395, 400}, - {416, 419, 399, 389}, - {435, 423, 393, 384}, - {407, 433, 412, 384}, - {422, 437, 382, 397}, - {404, 441, 399, 394}, - {433, 427, 395, 399}, - {432, 423, 340, 384}, - {401, 452, 382, 390}, - {440, 427, 379, 388}, - {423, 429, 399, 395}, - {379, 428, 306, 405}, - {449, 418, 387, 391}, - {425, 406, 391, 395}, - {432, 401, 403, 403},}; - v4si_t r_pst[16] = {{586, 575, 709, 686}, - {610, 571, 690, 686}, - {592, 572, 689, 691}, - {618, 575, 687, 687}, - {593, 571, 711, 681}, - {593, 592, 706, 679}, - {596, 575, 706, 686}, - {594, 581, 701, 681}, - {584, 574, 707, 690}, - {578, 581, 720, 697}, - {581, 584, 712, 696}, - {582, 591, 712, 695}, - {598, 577, 689, 704}, - {599, 583, 696, 690}, - {586, 595, 688, 692}, - {596, 596, 684, 688},}; - v4si_t p_pst[24] = {{164, 231, 161, 197}, - {199, 158, 194, 215}, - {144, 170, 146, 224}, - {91, 138, 149, 202}, - {94, 167, 111, 130}, - {129, 174, 110, 152}, - {119, 161, 96, 149}, - {118, 153, 102, 122}, - {108, 112, 107, 110}, - {109, 114, 100, 120}, - {91, 114, 109, 116}, - {89, 111, 105, 107}, - {97, 117, 115, 101}, - {105, 102, 112, 106}, - {110, 103, 105, 105}, - {103, 120, 108, 93}, - {92, 95, 115, 99}, - {90, 82, 104, 105}, - {106, 96, 96, 96}, - {99, 88, 103, 92}, - {103, 98, 97, 101}, - {96, 98, 104, 103}, - {107, 104, 93, 95}, - {104, 83, 91, 89},}; - v4si_t k_pst[16] = {{-82, -43, 15, -11}, - {-47, -89, 35, 16}, - {-47, -75, 57, 10}, - {-23, -133, 56, 16}, - {8, 35, -6, -11}, - {6, -31, -11, 14}, - {-19, -61, 6, 12}, - {-2, -100, 4, 17}, - {37, 45, -42, -12}, - {-4, -25, 2, 14}, - {-36, -91, 13, 27}, - {-66, -115, 20, 29}, - {54, 83, -72, -48}, - {44, 38, -12, -13}, - {-11, 19, 13, 0}, - {-19, -13, 6, 5},}; + v4si_t n_pst[16] = {{408,398,554,306},{403,430,493,329},{420,419,480,353},{424,418,462,370},{413,386,519,296},{426,402,483,323},{428,420,427,353},{406,436,471,354},{415,356,474,295},{412,375,515,305},{410,410,489,324},{435,410,456,342},{212,294,486,252},{405,367,531,296},{387,361,522,310},{386,377,527,321},}; + v4si_t q_pst[16] = {{1291,1326,1345,1207},{1263,1341,1429,1214},{1301,1301,1320,1256},{1288,1294,1365,1286},{1287,1333,1381,1177},{1320,1328,1296,1218},{1317,1320,1352,1240},{1311,1308,1313,1259},{1321,1314,1314,1226},{1250,1344,1407,1188},{1318,1325,1265,1252},{1332,1327,1272,1254},{1294,1326,1363,1194},{1343,1285,1336,1221},{1326,1312,1272,1230},{1334,1337,1234,1233},}; + v4si_t b_pst[16] = {{361,428,493,346},{413,399,461,369},{401,420,445,380},{426,419,425,386},{422,446,482,340},{423,446,434,363},{421,460,450,370},{420,429,462,381},{400,406,445,346},{425,470,442,354},{430,425,457,359},{426,435,450,374},{401,404,467,345},{424,384,444,355},{421,399,488,358},{406,400,522,353},}; + v4si_t r_pst[16] = {{581,560,781,652},{567,569,772,654},{575,564,777,664},{588,567,774,660},{572,564,790,653},{595,557,789,659},{609,549,769,663},{587,580,772,655},{562,557,778,664},{545,587,817,660},{571,571,795,667},{584,585,772,660},{610,572,748,667},{609,567,759,665},{602,601,752,663},{606,610,719,666},}; + v4si_t p_pst[24] = {{195,186,202,176},{73,212,189,173},{128,165,113,204},{152,155,218,166},{74,189,159,118},{151,196,112,114},{134,165,135,123},{131,165,98,114},{117,108,116,110},{110,114,120,110},{83,123,127,105},{107,115,116,101},{109,109,117,100},{98,98,114,102},{115,97,103,103},{93,125,111,85},{91,98,110,97},{91,72,118,104},{109,93,102,98},{99,81,113,91},{92,100,119,97},{105,107,118,100},{109,111,103,96},{118,92,95,78},}; + v4si_t k_pst[16] = {{-205,-38,59,-7},{-269,-25,95,-4},{-319,-42,94,-3},{-275,-65,103,-11},{3,-33,0,5},{-121,-13,34,7},{-148,-74,43,10},{-305,-84,63,4},{41,51,-42,-3},{-20,-11,-3,17},{-112,-91,23,28},{-136,-122,20,27},{81,84,-102,-23},{48,56,-8,-11},{13,-24,4,13},{-10,-29,-17,7},}; // Pawn structure - v4si_t isolated[2] = {{-8, -7, 6, -4}, - {-16, -18, 2, 0},}; - v4si_t backwards[2] = {{-6, 1, -2, -5}, - {-27, -12, -22, -11},}; - v4si_t semi_backwards[2] = {{0, 5, -2, 3}, - {-10, -11, 0, -1},}; - v4si_t paired[2] = {{10, 10, 4, 3}, - {9, 6, 19, 4},}; - v4si_t detached[2] = {{-5, -6, -1, -5}, - {3, -4, -8, -6},}; - v4si_t doubled[2] = {{5, -10, -20, -18}, - {6, 17, -15, -38},}; - v4si_t chain[5] = {{17, 21, 22, 17}, - {14, 9, 11, 14}, - {15, 20, 16, 20}, - {12, 76, 72, 15}, - {45, 285, 144, -40},}; - v4si_t passed[6] = {{-13, -16, -44, -40}, - {-22, -23, -4, -15}, - {-16, -19, 41, 23}, - {26, -3, 73, 67}, - {29, -6, 100, 125}, - {-14, 18, 99, 132},}; - v4si_t candidate[4] = {{-18, -18, -8, -8}, - {-18, -2, 13, -1}, - {-18, 14, 27, 15}, - {46, 54, 116, 39},}; + v4si_t isolated[2] = {{-7,-4,6,5},{-16,-15,5,-2},}; + v4si_t backwards[2] = {{-7,1,-11,3},{-25,0,-48,-11},}; + v4si_t semi_backwards[2] = {{1,3,-4,8},{-25,-8,-15,2},}; + v4si_t paired[2] = {{9,17,6,-2},{2,6,13,-7},}; + v4si_t detached[2] = {{-3,-7,-8,-6},{-6,-1,7,-9},}; + v4si_t doubled[2] = {{5,-5,-22,-24},{9,24,-12,-37},}; + v4si_t chain[5] = {{16,26,25,12},{15,15,27,2},{28,8,29,18},{-57,121,124,-10},{6,497,229,-138},}; + v4si_t passed[6] = {{-26,-2,-111,-54},{13,-11,-72,-33},{29,-44,-22,5},{35,-29,35,39},{-14,-53,79,122},{-121,15,157,126},}; + v4si_t candidate[4] = {{-18,-9,-24,4},{-2,2,-23,1},{25,-3,-1,15},{111,-24,99,54},}; // Interaction of pieces and pawn structure - v4si_t king_tropism[2] = {{-6, -6, 5, 0}, - {-1, 0, 6, 5},}; - v4si_t passer_tropism[2] = {{6, 2, -19, -8}, - {2, 0, 16, 15},}; - v4si_t blocked[2] = {{-9, -6, -10, -4}, - {-3, -5, -17, -37},}; - v4si_t pos_r_open_file = {28, 41, 37, 12}; - v4si_t pos_r_own_half_open_file = {19, 20, -10, -1}; - v4si_t pos_r_other_half_open_file = {19, 15, 15, 6}; - v4si_t outpost[2] = {{-11, 4, 12, 1}, - {8, -6, -1, 12},}; - v4si_t outpost_hole[2] = {{38, 32, 9, 15}, - {22, 45, -8, -4},}; - v4si_t outpost_half[2] = {{-1, -8, 6, -19}, - {-6, 1, 34, -8},}; - v4si_t ks_pawn_shield[4] = {{56, -31, 29, 12}, - {38, -8, 11, 11}, - {27, 16, 2, 0}, - {15, 39, 5, -13},}; + v4si_t king_tropism[2] = {{-5,-12,2,-1},{3,2,9,5},}; + v4si_t passer_tropism[2] = {{10,1,-11,-10},{0,-1,25,18},}; + v4si_t blocked[2] = {{-28,1,-1,-8},{-3,2,-11,-46},}; + v4si_t pos_r_open_file = {31,42,64,-26}; + v4si_t pos_r_own_half_open_file = {25,20,-2,-11}; + v4si_t pos_r_other_half_open_file = {27,-1,69,-19}; + v4si_t outpost[2] = {{-2,14,14,-10},{-3,-9,-11,6},}; + v4si_t outpost_hole[2] = {{14,22,52,14},{5,82,-18,-2},}; + v4si_t outpost_half[2] = {{8,-8,35,-34},{24,13,26,-31},}; + v4si_t ks_pawn_shield[4] = {{55,-30,26,5},{47,-6,1,15},{28,16,-13,-2},{13,45,6,-4},}; // King safety - int kat_zero = 9; - int kat_open_file = 23; - int kat_own_half_open_file = 16; - int kat_other_half_open_file = 13; - int kat_attack_weight[5] = {9, 16, 11, 10, 11,}; - int kat_defence_weight[5] = {8, 3, 4, 2, 1,}; - int kat_table_scale = 46; - int kat_table_translate = 78; - v4si_t kat_table_max = {445, 445, -20, -101}; + int kat_zero = 13; + int kat_open_file = 33; + int kat_own_half_open_file = 26; + int kat_other_half_open_file = 12; + int kat_attack_weight[5] = {7,12,9,7,9,}; + int kat_defence_weight[5] = {2,6,5,3,3,}; + int kat_table_scale = 47; + int kat_table_translate = 77; + v4si_t kat_table_max = {458,454,60,-198}; // Dynamic threats - v4si_t undefended[5] = {{-1, -10, 0, 4}, - {-17, -16, 14, -4}, - {-14, -14, 6, -7}, - {4, -4, -9, -7}, - {-18, -13, 19, 2},}; - v4si_t overprotected[5] = {{2, 4, -10, 4}, - {15, 7, -4, 14}, - {2, 6, 19, 16}, - {7, 7, 19, 7}, - {6, 3, 28, 20},}; + v4si_t undefended[5] = {{-4,-16,-6,7},{-21,-18,40,-23},{-15,-5,17,-18},{2,-5,28,-19},{-13,-15,42,-19},}; + v4si_t overprotected[5] = {{4,6,-4,-1},{10,4,24,8},{4,4,24,0},{5,4,40,-6},{-8,7,46,-16},}; v4si_t threat_matrix[4][5] = { - {{46, 3, 35, -10}, {62, 52, 5, -9}, {81, 36, 13, 40}, {50, 52, -24, -48}, {50, 44, -102, -56},}, - {{-7, -12, 8, 1}, {140, -31, 169, 169}, {28, 23, 6, 30}, {48, 65, 49, -21}, {22, 41, -88, -36},}, - {{7, -3, 31, 12}, {31, 27, 61, 19}, {-11, -11, -37, -37}, {30, 15, 25, -7}, {43, 20, 91, 112},}, - {{0, -4, 21, 18}, {8, 15, 31, 16}, {27, 28, 16, 18}, {256, 5, -5, -9}, {75, 62, 34, -9},}, + {{-17,-14,44,-47},{41,26,16,-24},{84,27,32,26},{83,22,14,-62},{39,4,109,-59},}, + {{-5,-17,3,5},{-59,-2,-143,67},{23,13,111,10},{17,83,85,-26},{33,-6,48,-39},}, + {{6,-7,17,10},{17,18,56,13},{36,-179,-115,-108},{10,-19,23,-5},{50,1,41,-60},}, + {{5,-12,31,5},{16,11,12,12},{23,28,13,7},{307,-183,71,-180},{68,58,117,-156},}, }; // Other positional factors - v4si_t pos_bishop_pair{24, 33, 75, 70}; - v4si_t mat_opp_bishop[3] = {{-18, -17, 32, 67}, - {-7, -17, 67, 70}, - {70, 4, 86, 64},}; - v4si_t pos_r_trapped = {-9, -73, -9, -17}; - v4si_t pos_r_behind_own_passer = {-7, 10, -22, -5}; - v4si_t pos_r_behind_enemy_passer = {-52, 40, 66, 57}; - v4si_t pos_mob[4] = {{11, 7, 24, 4}, - {10, 7, 13, 6}, - {3, 3, 13, 4}, - {5, 4, 16, 6},}; - - // TODO: Evaluate better + v4si_t pos_bishop_pair {41,48,61,63}; + v4si_t mat_opp_bishop[3] = {{28,-52,-46,122},{108,-66,-32,108},{46,-26,122,66},}; + v4si_t pos_r_trapped = {-39,-62,60,-53}; + v4si_t pos_r_behind_own_passer = {-25,33,-22,10}; + v4si_t pos_r_behind_enemy_passer = {139,-7,67,42}; + v4si_t pos_mob[4] = {{11,8,34,-6},{9,7,24,-4},{-1,6,22,-2},{5,5,23,-3},}; }; struct processed_params_t : public eval_params_t { @@ -253,6 +112,7 @@ class alignas(64) evaluator_t { * @param pawn_hash_size size of the pawn hash table in bytes */ evaluator_t(const processed_params_t ¶ms, size_t pawn_hash_size); + ~evaluator_t(); // This object has a (potentially large) pawn hash table - don't copy @@ -273,11 +133,6 @@ class alignas(64) evaluator_t { */ void prefetch(U64 pawn_hash); - /** - * Initialise evaluation tables. Must be called before any evaluators are constructed - */ - static void eval_init(); - /** * Computes the game phase of the given position, used to taper evaluation. * Topple's search uses this value to guide time management. diff --git a/main.cpp b/main.cpp index ce0d073..c2036a5 100644 --- a/main.cpp +++ b/main.cpp @@ -11,10 +11,6 @@ U64 perft(board_t &, int); int main(int argc, char *argv[]) { - // Initialise engine - init_tables(); - evaluator_t::eval_init(); - // Board std::unique_ptr board = nullptr; diff --git a/pawns.cpp b/pawns.cpp index 0c1df32..bdb00c4 100644 --- a/pawns.cpp +++ b/pawns.cpp @@ -146,15 +146,15 @@ pawns::structure_t::structure_t(const processed_params_t ¶ms, U64 kp_hash, U } // Calculate tapering factor - int accumulator = params.pt_island * (pawns::island_count(w_pawns) + pawns::island_count(b_pawns)); + int accumulator = 0; U64 blocked_b_pawns = pawns::stop_squares(w_pawns) & b_pawns; for (int file = 0; file < 8; file++) { U64 on_file = file_mask(file) & (w_pawns | b_pawns); if (blocked_b_pawns & on_file) { // Blocked file accumulator += params.pt_blocked_file[file_edge_distance(file)]; - } else if (!on_file) { // No pawns - open file - accumulator += params.pt_open_file[file_edge_distance(file)]; + } else if ((on_file & w_pawns) && (on_file & b_pawns)) { + accumulator += params.pt_closed_file[file_edge_distance(file)]; } } diff --git a/testing/runner.cpp b/testing/runner.cpp deleted file mode 100644 index 1f156ed..0000000 --- a/testing/runner.cpp +++ /dev/null @@ -1,17 +0,0 @@ -// -// Created by Vincent on 27/09/2017. -// - -#define CATCH_CONFIG_RUNNER -#include "catch2/catch.hpp" - -#include "../bb.h" -#include "../hash.h" -#include "../eval.h" - -int main(int argc, char* argv[]) { - init_tables(); - evaluator_t::eval_init(); - - return Catch::Session().run(argc, argv); -} \ No newline at end of file diff --git a/testing/test_bb.cpp b/testing/test_bb.cpp index 9b95984..15d4438 100644 --- a/testing/test_bb.cpp +++ b/testing/test_bb.cpp @@ -2,7 +2,7 @@ // Created by Vincent on 27/09/2017. // -#include +#include #include "util.h" @@ -137,7 +137,7 @@ TEST_CASE("Bitboard engine") { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}); - REQUIRE(bb_normal_moves::pawn_moves_x1[WHITE][square] == expected); + REQUIRE(bb_tables::pawn_moves_x1[WHITE][square] == expected); square = A7; expected = c_u64({0, 0, 0, 0, 0, 0, 0, 0, @@ -149,7 +149,7 @@ TEST_CASE("Bitboard engine") { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}); - REQUIRE(bb_normal_moves::pawn_moves_x1[BLACK][square] == expected); + REQUIRE(bb_tables::pawn_moves_x1[BLACK][square] == expected); } SECTION("King") { diff --git a/testing/test_board.cpp b/testing/test_board.cpp index b5213f9..e9da016 100644 --- a/testing/test_board.cpp +++ b/testing/test_board.cpp @@ -3,7 +3,7 @@ // #include -#include +#include #include "util.h" #include "../board.h" @@ -228,7 +228,7 @@ TEST_CASE("Legality") { REQUIRE(board1.is_incheck()); board_t board2("rnbqkb1r/ppp2ppp/3p4/8/4n3/3N4/PPPP1PPP/RNBQKB1R w KQkq - 0 5"); - INFO(((find_moves(PAWN, WHITE, D2, board2.all()) & single_bit(D4)) == 0)) + INFO(((find_moves(PAWN, WHITE, D2, board2.all()) & single_bit(D4)) == 0)); REQUIRE(!board2.is_pseudo_legal(board2.parse_move("d2d4"))); board_t board3("rnbq1k1r/pp1Pbppp/2p5/8/2B5/8/PPP1NnPP/RNBQK2R w KQ - 1 8"); diff --git a/testing/test_hash.cpp b/testing/test_hash.cpp index 164f0bf..547d1f4 100644 --- a/testing/test_hash.cpp +++ b/testing/test_hash.cpp @@ -2,7 +2,7 @@ // Created by Vincent on 23/06/2019. // -#include +#include #include #include "util.h" diff --git a/testing/test_perft.cpp b/testing/test_perft.cpp index d702f43..29149da 100644 --- a/testing/test_perft.cpp +++ b/testing/test_perft.cpp @@ -2,7 +2,7 @@ // Created by Vincent on 30/09/2017. // -#include "catch2/catch.hpp" +#include "catch2/catch_all.hpp" #include "util.h" #include "../board.h" diff --git a/testing/test_see.cpp b/testing/test_see.cpp index 8ac9c26..5241b7f 100644 --- a/testing/test_see.cpp +++ b/testing/test_see.cpp @@ -2,7 +2,7 @@ // Created by Vincent on 01/06/2018. // -#include +#include #include "util.h" #include "../board.h" diff --git a/texeltuning/main.cpp b/texeltuning/main.cpp index eec1fb3..9dbe82e 100644 --- a/texeltuning/main.cpp +++ b/texeltuning/main.cpp @@ -24,10 +24,6 @@ double get_result(const std::string &result) { } int main(int argc, char *argv[]) { - // Initialise engine - init_tables(); - evaluator_t::eval_init(); - // Startup std::cout << "ToppleTexelTune v" << TOPPLE_TUNE_VER << " (c) Vincent Tang 2020" << std::endl; @@ -151,7 +147,7 @@ int main(int argc, char *argv[]) { int times = std::stoi(parameter); for(int i = 0; i < times; i++) { - tuner.random_optimise(reinterpret_cast (tuner.get_current_params()->pt_blocked_file), 9, n_iter); + tuner.random_optimise(reinterpret_cast (tuner.get_current_params()->pt_blocked_file), 12, n_iter); } tuner.print_params(); diff --git a/texeltuning/texel.cpp b/texeltuning/texel.cpp index c4f9e68..e50a797 100644 --- a/texeltuning/texel.cpp +++ b/texeltuning/texel.cpp @@ -22,7 +22,7 @@ texel_t::texel_t(unsigned int threads, size_t entries, std::vector &pos std::cout << "starting error: " << current_error << std::endl; // Pick scaling constant - //current_error = momentum_optimise(&scaling_constant, current_error, 500, 1); + current_error = momentum_optimise(&scaling_constant, current_error, 500, 1); std::cout << "scaling constant = " << scaling_constant << std::endl; } @@ -198,13 +198,12 @@ void texel_t::print_params() { } std::cout << "};" << std::endl; - std::cout << "int pt_open_file[4] = {"; - for (const auto ¶m : current_params.pt_open_file) { + std::cout << "int pt_closed_file[4] = {"; + for (const auto ¶m : current_params.pt_closed_file) { std::cout << param << ","; } std::cout << "};" << std::endl; - std::cout << "int pt_island = " << current_params.pt_island << ";" << std::endl; std::cout << "int pt_max = " << current_params.pt_max << ";" << std::endl; std::cout << "// Piece-square tables" << std::endl;