diff --git a/src/endgame.cpp b/src/endgame.cpp index e344742d3b4..84788f9bcfe 100644 --- a/src/endgame.cpp +++ b/src/endgame.cpp @@ -351,6 +351,18 @@ Value Endgame::operator()(const Position& pos) const { template<> Value Endgame::operator()(const Position&) const { return VALUE_DRAW; } +// Any vs K is drawn except for cornered N vs K (not checked). +#ifdef HORDE +template<> +ScaleFactor Endgame::operator()(const Position& pos) const { + + assert(pos.variant() == HORDE_VARIANT); + assert(pos.count(strongSide) == 1); + assert(pos.count(weakSide) == 1); + return SCALE_FACTOR_DRAW; +} +#endif + /// KB and one or more pawns vs K. It checks for draws with rook pawns and /// a bishop of the wrong color. If such a draw is detected, SCALE_FACTOR_DRAW /// is returned. If not, the return value is SCALE_FACTOR_NONE, i.e. no scaling diff --git a/src/endgame.h b/src/endgame.h index b9da1bfdcb5..96ca012ab2f 100644 --- a/src/endgame.h +++ b/src/endgame.h @@ -59,6 +59,9 @@ enum EndgameCode { KQKR, // KQ vs KR SCALING_FUNCTIONS, +#ifdef HORDE + AK, // Any vs K +#endif KBPsK, // KB and pawns vs K KQKRPs, // KQ vs KR and pawns KRPKR, // KRP vs KR diff --git a/src/material.cpp b/src/material.cpp index 5e045a63b56..5397a5e8436 100644 --- a/src/material.cpp +++ b/src/material.cpp @@ -357,6 +357,9 @@ namespace { Endgame EvaluateAtomicKXK[] = { Endgame(WHITE), Endgame(BLACK) }; #endif +#ifdef HORDE + Endgame ScaleHordeAK[] = { Endgame(WHITE), Endgame(BLACK) }; +#endif Endgame ScaleKBPsK[] = { Endgame(WHITE), Endgame(BLACK) }; Endgame ScaleKQKRPs[] = { Endgame(WHITE), Endgame(BLACK) }; Endgame ScaleKPsK[] = { Endgame(WHITE), Endgame(BLACK) }; @@ -520,8 +523,9 @@ Entry* probe(const Position& pos) { return e; } - if (pos.variant() == CHESS_VARIANT) + switch (pos.variant()) { + case CHESS_VARIANT: // 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. @@ -567,6 +571,15 @@ Entry* probe(const Position& pos) { 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); + break; +#ifdef HORDE + case HORDE_VARIANT: + for (Color c = WHITE; c <= BLACK; ++c) + if (pos.is_horde_color(c) && pos.count() == 2) + e->scalingFunction[c] = &ScaleHordeAK[c]; + break; +#endif + default: break; } // Evaluate the material imbalance. We use PIECE_TYPE_NONE as a place holder