From: Fabian Fichter Date: Sat, 7 Dec 2019 15:19:10 +0000 (+0100) Subject: Fix endgame evaluation for large-board version X-Git-Url: http://winboard.nl/cgi-bin?a=commitdiff_plain;h=edb325a2e20743f568dd8f74695c58ffc47b2ce5;p=fairystockfish.git Fix endgame evaluation for large-board version Map squares to 8x8 board to retain endgame evaluation logic. Allows to enable endgame evaluation for large-board variants. capablanca STC LLR: 2.99 (-2.94,2.94) [-10.00,5.00] Total: 2512 W: 980 L: 941 D: 591 http://www.variantfishtest.org:6543/tests/view/5dea40ff6e23db1ffe4a289c capablanca LTC LLR: 2.98 (-2.94,2.94) [-10.00,5.00] Total: 1443 W: 534 L: 490 D: 419 http://www.variantfishtest.org:6543/tests/view/5dea8b666e23db1ffe4a28a6 makruk STC LLR: 3.00 (-2.94,2.94) [-10.00,5.00] Total: 1810 W: 158 L: 124 D: 1528 http://www.variantfishtest.org:6543/tests/view/5dea3f546e23db1ffe4a289a makruk LTC LLR: 3.01 (-2.94,2.94) [-10.00,5.00] Total: 795 W: 77 L: 41 D: 677 http://www.variantfishtest.org:6543/tests/view/5dea8b7a6e23db1ffe4a28a8 chess STC LLR: 2.99 (-2.94,2.94) [-10.00,5.00] Total: 4321 W: 959 L: 936 D: 2426 http://www.variantfishtest.org:6543/tests/view/5dea398f6e23db1ffe4a2896 chess LTC LLR: 2.96 (-2.94,2.94) [-10.00,5.00] Total: 3451 W: 667 L: 640 D: 2144 http://www.variantfishtest.org:6543/tests/view/5dea633a6e23db1ffe4a28a4 --- diff --git a/src/endgame.cpp b/src/endgame.cpp index a62bfce..9cc305b 100644 --- a/src/endgame.cpp +++ b/src/endgame.cpp @@ -86,10 +86,17 @@ namespace { assert(pos.count(strongSide) == 1); - if (file_of(pos.square(strongSide)) >= FILE_E) - sq = Square(int(sq) ^ 7); // Mirror SQ_H1 -> SQ_A1 + if (file_of(pos.square(strongSide)) > pos.max_file() / 2) + sq = Square(sq + pos.max_file() - 2 * file_of(sq)); // Mirror SQ_H1 -> SQ_A1 - return strongSide == WHITE ? sq : ~sq; + return relative_square(strongSide, sq, pos.max_rank()); + } + + // Map the square to an 8x8 board + Square map_to_standard_board(const Position& pos, Square s) { + File f = file_of(s) > pos.max_file() / 2 ? File(FILE_H - pos.max_file() + file_of(s)) : file_of(s); + Rank r = rank_of(s) > pos.max_rank() / 2 ? Rank(RANK_8 - pos.max_rank() + rank_of(s)) : rank_of(s); + return Square(r * 8 + f); } } // namespace @@ -148,7 +155,7 @@ Value Endgame::operator()(const Position& pos) const { Value result = pos.non_pawn_material(strongSide) + pos.count(strongSide) * PawnValueEg - + PushToEdges[loserKSq] + + PushToEdges[map_to_standard_board(pos, loserKSq)] + PushClose[distance(winnerKSq, loserKSq)]; if ( pos.count(strongSide) @@ -186,7 +193,7 @@ Value Endgame::operator()(const Position& pos) const { Value result = VALUE_KNOWN_WIN + PushClose[distance(winnerKSq, loserKSq)] - + PushToCorners[opposite_colors(bishopSq, SQ_A1) ? ~loserKSq : loserKSq]; + + PushToCorners[map_to_standard_board(pos, relative_square(opposite_colors(bishopSq, SQ_A1) ? BLACK : WHITE, loserKSq, pos.max_rank()))]; assert(abs(result) < VALUE_MATE_IN_MAX_PLY); return strongSide == pos.side_to_move() ? result : -result; @@ -280,7 +287,7 @@ Value Endgame::operator()(const Position& pos) const { assert(verify_material(pos, strongSide, RookValueMg, 0)); assert(verify_material(pos, weakSide, BishopValueMg, 0)); - Value result = Value(PushToEdges[pos.square(weakSide)]); + Value result = Value(PushToEdges[map_to_standard_board(pos, pos.square(weakSide))]); return strongSide == pos.side_to_move() ? result : -result; } @@ -295,7 +302,7 @@ Value Endgame::operator()(const Position& pos) const { Square bksq = pos.square(weakSide); Square bnsq = pos.square(weakSide); - Value result = Value(PushToEdges[bksq] + PushAway[distance(bksq, bnsq)]); + Value result = Value(PushToEdges[map_to_standard_board(pos, bksq)] + PushAway[distance(bksq, bnsq)]); return strongSide == pos.side_to_move() ? result : -result; } @@ -340,7 +347,7 @@ Value Endgame::operator()(const Position& pos) const { Value result = QueenValueEg - RookValueEg - + PushToEdges[loserKSq] + + PushToEdges[map_to_standard_board(pos, loserKSq)] + PushClose[distance(winnerKSq, loserKSq)]; return strongSide == pos.side_to_move() ? result : -result; @@ -356,7 +363,7 @@ Value Endgame::operator()(const Position& pos) const { Value result = 2 * KnightValueEg - PawnValueEg - + PushToEdges[pos.square(weakSide)]; + + PushToEdges[map_to_standard_board(pos, pos.square(weakSide))]; return strongSide == pos.side_to_move() ? result : -result; } @@ -377,7 +384,7 @@ Value Endgame::operator()(const Position& pos) const { Value result = pos.non_pawn_material(strongSide) + pos.count(strongSide) * PawnValueEg - + PushToEdges[loserKSq] + + PushToEdges[map_to_standard_board(pos, loserKSq)] + PushClose[distance(winnerKSq, loserKSq)]; if ( pos.count(strongSide) >= 3 @@ -420,7 +427,7 @@ Value Endgame::operator()(const Position& pos) const { Value result = VALUE_KNOWN_WIN + PushClose[distance(winnerKSq, loserKSq)] - + PushToOpposingSideEdges[strongSide == WHITE ? loserKSq : ~loserKSq]; + + PushToOpposingSideEdges[map_to_standard_board(pos, relative_square(strongSide, loserKSq, pos.max_rank()))]; return strongSide == pos.side_to_move() ? result : -result; } @@ -443,12 +450,12 @@ Value Endgame::operator()(const Position& pos) const { // to drive the enemy toward corners A8 or H1. if (opposite_colors(fersSq, SQ_A1)) { - winnerKSq = ~winnerKSq; - loserKSq = ~loserKSq; + winnerKSq = relative_square(BLACK, winnerKSq, pos.max_rank()); + loserKSq = relative_square(BLACK, loserKSq, pos.max_rank()); } Value result = Value(PushClose[distance(winnerKSq, loserKSq)]) - + PushToCorners[loserKSq]; + + PushToCorners[map_to_standard_board(pos, loserKSq)] / 10; return strongSide == pos.side_to_move() ? result : -result; } @@ -466,7 +473,7 @@ Value Endgame::operator()(const Position& pos) const { Value result = KnightValueEg + SilverValueEg + FersValueEg - RookValueEg + PushClose[distance(winnerKSq, loserKSq)] - + PushToOpposingSideEdges[strongSide == WHITE ? loserKSq : ~loserKSq]; + + PushToOpposingSideEdges[map_to_standard_board(pos, relative_square(strongSide, loserKSq, pos.max_rank()))]; return strongSide == pos.side_to_move() ? result : -result; } @@ -484,7 +491,7 @@ Value Endgame::operator()(const Position& pos) const { Value result = VALUE_KNOWN_WIN + PushClose[distance(winnerKSq, loserKSq)] - + PushToOpposingSideEdges[strongSide == WHITE ? loserKSq : ~loserKSq]; + + PushToOpposingSideEdges[map_to_standard_board(pos, relative_square(strongSide, loserKSq, pos.max_rank()))]; return strongSide == pos.side_to_move() ? result : -result; } diff --git a/src/variant.cpp b/src/variant.cpp index 1a24cc4..deefb9e 100644 --- a/src/variant.cpp +++ b/src/variant.cpp @@ -567,7 +567,7 @@ namespace { return v; } Variant* capablanca_variant() { - Variant* v = fairy_variant_base(); + Variant* v = chess_variant(); v->pieceToCharTable = "PNBRQ..AC............Kpnbrq..ac............k"; v->maxRank = RANK_8; v->maxFile = FILE_J; @@ -584,6 +584,7 @@ namespace { v->startFen = "rnabqkbcnr/pppppppppp/10/10/10/10/PPPPPPPPPP/RNABQKBCNR[] w KQkq - 0 1"; v->pieceDrops = true; v->capturesToHand = true; + v->endgameEval = false; return v; } Variant* caparandom_variant() { @@ -597,7 +598,7 @@ namespace { return v; } Variant* janus_variant() { - Variant* v = fairy_variant_base(); + Variant* v = chess_variant(); v->pieceToCharTable = "PNBRQ............J...Kpnbrq............J...k"; v->maxRank = RANK_8; v->maxFile = FILE_J; @@ -609,7 +610,7 @@ namespace { return v; } Variant* modern_variant() { - Variant* v = fairy_variant_base(); + Variant* v = chess_variant(); v->pieceToCharTable = "PNBRQ..M.............Kpnbrq..m.............k"; v->maxRank = RANK_9; v->maxFile = FILE_I; @@ -622,7 +623,7 @@ namespace { return v; } Variant* chancellor_variant() { - Variant* v = fairy_variant_base(); + Variant* v = chess_variant(); v->pieceToCharTable = "PNBRQ...........CKpnbrq...........ck"; v->maxRank = RANK_9; v->maxFile = FILE_I; @@ -642,7 +643,7 @@ namespace { return v; } Variant* centaur_variant() { - Variant* v = fairy_variant_base(); + Variant* v = chess_variant(); v->pieceToCharTable = "PNBRQ...............CKpnbrq...............ck"; v->maxRank = RANK_8; v->maxFile = FILE_J;