From: protonspring Date: Tue, 18 Feb 2020 16:10:58 +0000 (-0700) Subject: Updated KNNKP endgame. X-Git-Url: https://git.sesse.net/?p=stockfish;a=commitdiff_plain;h=ab930f8d3f4a657f493305559756e85534c88911;hp=10ead8a724671132df60ca2e23ddcad7eff7b3e5 Updated KNNKP endgame. This is a patch that significantly improves playing KNNKP endgames: ``` Score of 2553 vs master: 132 - 38 - 830 [0.547] 1000 Elo difference: 32.8 +/- 8.7, LOS: 100.0 %, DrawRatio: 83.0 % ``` At the same time it reduces the evaluation of this mostly draw engame from ~7.5 to ~1.5 This patch does not regress against master in normal games: STC LLR: 2.94 (-2.94,2.94) {-1.50,0.50} Total: 96616 W: 18459 L: 18424 D: 59733 Ptnml(0-2): 1409, 10812, 23802, 10905, 1380 http://tests.stockfishchess.org/tests/view/5e49dfe6f8d1d52b40cd31bc LTC LLR: 2.95 (-2.94,2.94) {-1.50,0.50} Total: 49726 W: 6340 L: 6304 D: 37082 Ptnml(0-2): 239, 4227, 15906, 4241, 250 http://tests.stockfishchess.org/tests/view/5e4ab9ee16fb3df8c4cc01d0 Theory: KNNK is a dead draw, however the presence of the additional weakSide pawn opens up some mate opportunities. The idea is to block the pawn (preferably behind the Troitsky line) with one of the knights and press the weakSide king into a corner. If we can stalemate the king, we release the pawn with the knight (to avoid actual stalemate), and use the knight to complete the mate before the pawn promotes. This is also why there is an additional penalty for advancement of the pawn. closes https://github.com/official-stockfish/Stockfish/pull/2553 Bench: 4981770 --- diff --git a/src/endgame.cpp b/src/endgame.cpp index 6745ee26..74e16fa6 100644 --- a/src/endgame.cpp +++ b/src/endgame.cpp @@ -310,16 +310,17 @@ Value Endgame::operator()(const Position& pos) const { } -/// KNN vs KP. Simply push the opposing king to the corner +/// KNN vs KP. Very drawish, but there are some mate opportunities if we can +// press the weakSide King to a corner before the pawn advances too much. template<> Value Endgame::operator()(const Position& pos) const { assert(verify_material(pos, strongSide, 2 * KnightValueMg, 0)); assert(verify_material(pos, weakSide, VALUE_ZERO, 1)); - Value result = 2 * KnightValueEg - - PawnValueEg - + PushToEdges[pos.square(weakSide)]; + Value result = PawnValueEg + + 2 * PushToEdges[pos.square(weakSide)] + - 10 * relative_rank(weakSide, pos.square(weakSide)); return strongSide == pos.side_to_move() ? result : -result; }