From: Fabian Fichter Date: Sat, 9 Feb 2019 23:39:54 +0000 (+0100) Subject: Merge official-stockfish/master X-Git-Url: http://winboard.nl/cgi-bin?a=commitdiff_plain;h=4ac3c521d0f55dc5d7d6273a57100e55acf937f7;p=fairystockfish.git Merge official-stockfish/master --- 4ac3c521d0f55dc5d7d6273a57100e55acf937f7 diff --cc src/endgame.h index cb982ec,69a9f17..bbcbb6f --- a/src/endgame.h +++ b/src/endgame.h @@@ -121,10 -115,29 +122,35 @@@ class Endgames std::pair, Map> maps; public: - Endgames(); + Endgames() { + + add("KPK"); + add("KNNK"); + add("KBNK"); + add("KRKP"); + add("KRKB"); + add("KRKN"); + add("KQKP"); + add("KQKR"); + ++ // Fairy piece endgames ++ add("KNSK"); ++ add("KNFK"); ++ add("KNSFKR"); ++ add("KSFK"); ++ + add("KNPK"); + add("KNPKB"); + add("KRPKR"); + add("KRPKB"); + add("KBPKB"); + add("KBPKN"); + add("KBPPKB"); + add("KRPPKRP"); + } template - EndgameBase* probe(Key key) { + const EndgameBase* probe(Key key) { return map().count(key) ? map()[key].get() : nullptr; } }; diff --cc src/material.cpp index 6d9f72c,64a5bff..ac11142 --- a/src/material.cpp +++ b/src/material.cpp @@@ -144,99 -135,76 +144,99 @@@ Entry* probe(const Position& pos) Value npm = std::max(EndgameLimit, std::min(npm_w + npm_b, MidgameLimit)); // Map total non-pawn material into [PHASE_ENDGAME, PHASE_MIDGAME] - e->gamePhase = Phase(((npm - EndgameLimit) * PHASE_MIDGAME) / (MidgameLimit - EndgameLimit)); - - // Let's look if we have a specialized evaluation function for this particular - // material configuration. Firstly we look for a fixed configuration one, then - // for a generic one if the previous search failed. - if ((e->evaluationFunction = pos.this_thread()->endgames.probe(key)) != nullptr) - return e; - - for (Color c = WHITE; c <= BLACK; ++c) - if (is_KXK(pos, c)) - { - e->evaluationFunction = &EvaluateKXK[c]; - return e; - } - - // OK, we didn't find any special evaluation function for the current material - // configuration. Is there a suitable specialized scaling function? - const EndgameBase* sf; - - if ((sf = pos.this_thread()->endgames.probe(key)) != nullptr) + if (pos.captures_to_hand()) { - e->scalingFunction[sf->strongSide] = sf; // Only strong color assigned - return e; + npm = VALUE_ZERO; + for (PieceType pt : pos.piece_types()) + npm += (pos.count_in_hand(WHITE, pt) + pos.count_in_hand(BLACK, pt)) * PieceValue[MG][make_piece(WHITE, pt)]; + e->gamePhase = Phase(PHASE_MIDGAME * (MidgameLimit - std::min(npm, MidgameLimit)) / MidgameLimit); } - - // We didn't find any specialized scaling function, so fall back on generic - // ones that refer to more than one material distribution. Note that in this - // case we don't return after setting the function. - for (Color c = WHITE; c <= BLACK; ++c) + else + e->gamePhase = Phase(((npm - EndgameLimit) * PHASE_MIDGAME) / (MidgameLimit - EndgameLimit)); + +#ifdef LARGEBOARDS + // Disable endgame evaluation until it works independent of board size + if (false) +#else + if (pos.endgame_eval()) +#endif { - if (is_KBPsK(pos, c)) - e->scalingFunction[c] = &ScaleKBPsK[c]; - - else if (is_KQKRPs(pos, c)) - e->scalingFunction[c] = &ScaleKQKRPs[c]; - } + // Let's look if we have a specialized evaluation function for this particular + // material configuration. Firstly we look for a fixed configuration one, then + // for a generic one if the previous search failed. + if ((e->evaluationFunction = pos.this_thread()->endgames.probe(key)) != nullptr) + return e; - if (npm_w + npm_b == VALUE_ZERO && pos.pieces(PAWN)) // Only pawns on the board - { - if (!pos.count(BLACK)) + for (Color c = WHITE; c <= BLACK; ++c) + if (is_KFsPsK(pos, c)) + { + e->evaluationFunction = &EvaluateKFsPsK[c]; + return e; + } + + for (Color c = WHITE; c <= BLACK; ++c) + if (is_KXK(pos, c)) + { + e->evaluationFunction = &EvaluateKXK[c]; + return e; + } + + // OK, we didn't find any special evaluation function for the current material + // configuration. Is there a suitable specialized scaling function? - EndgameBase* sf; ++ const EndgameBase* sf; + + if ((sf = pos.this_thread()->endgames.probe(key)) != nullptr) { - assert(pos.count(WHITE) >= 2); - - e->scalingFunction[WHITE] = &ScaleKPsK[WHITE]; + e->scalingFunction[sf->strongSide] = sf; // Only strong color assigned + return e; } - else if (!pos.count(WHITE)) + + // We didn't find any specialized scaling function, so fall back on generic + // ones that refer to more than one material distribution. Note that in this + // case we don't return after setting the function. + for (Color c = WHITE; c <= BLACK; ++c) { - assert(pos.count(BLACK) >= 2); + if (is_KBPsK(pos, c)) + e->scalingFunction[c] = &ScaleKBPsK[c]; - e->scalingFunction[BLACK] = &ScaleKPsK[BLACK]; + else if (is_KQKRPs(pos, c)) + e->scalingFunction[c] = &ScaleKQKRPs[c]; } - else if (pos.count(WHITE) == 1 && pos.count(BLACK) == 1) + + if (npm_w + npm_b == VALUE_ZERO && pos.pieces(PAWN)) // Only pawns on the board { - // This is a special case because we set scaling functions - // for both colors instead of only one. - e->scalingFunction[WHITE] = &ScaleKPKP[WHITE]; - e->scalingFunction[BLACK] = &ScaleKPKP[BLACK]; + if (!pos.count(BLACK)) + { + assert(pos.count(WHITE) >= 2); + + e->scalingFunction[WHITE] = &ScaleKPsK[WHITE]; + } + else if (!pos.count(WHITE)) + { + assert(pos.count(BLACK) >= 2); + + e->scalingFunction[BLACK] = &ScaleKPsK[BLACK]; + } + else if (pos.count(WHITE) == 1 && pos.count(BLACK) == 1) + { + // This is a special case because we set scaling functions + // for both colors instead of only one. + e->scalingFunction[WHITE] = &ScaleKPKP[WHITE]; + e->scalingFunction[BLACK] = &ScaleKPKP[BLACK]; + } } - } - // Zero or just one pawn makes it difficult to win, even with a small material - // advantage. This catches some trivial draws like KK, KBK and KNK and gives a - // drawish scale factor for cases such as KRKBP and KmmKm (except for KBBKN). - if (!pos.count(WHITE) && npm_w - npm_b <= BishopValueMg) - e->factor[WHITE] = uint8_t(npm_w < RookValueMg ? SCALE_FACTOR_DRAW : - npm_b <= BishopValueMg ? 4 : 14); + // Zero or just one pawn makes it difficult to win, even with a small material + // advantage. This catches some trivial draws like KK, KBK and KNK and gives a + // drawish scale factor for cases such as KRKBP and KmmKm (except for KBBKN). + if (!pos.count(WHITE) && npm_w - npm_b <= BishopValueMg) + e->factor[WHITE] = uint8_t(npm_w < RookValueMg ? SCALE_FACTOR_DRAW : + npm_b <= BishopValueMg ? 4 : 14); - if (!pos.count(BLACK) && npm_b - npm_w <= BishopValueMg) - e->factor[BLACK] = uint8_t(npm_b < RookValueMg ? SCALE_FACTOR_DRAW : - npm_w <= BishopValueMg ? 4 : 14); + if (!pos.count(BLACK) && npm_b - npm_w <= BishopValueMg) + e->factor[BLACK] = uint8_t(npm_b < RookValueMg ? SCALE_FACTOR_DRAW : + npm_w <= BishopValueMg ? 4 : 14); + } // Evaluate the material imbalance. We use PIECE_TYPE_NONE as a place holder // for the bishop pair "extended piece", which allows us to be more flexible