Add KNNvKP Endgame Heuristic
authorKurtbusch <yoshi2jared@gmail.com>
Fri, 4 Jan 2019 23:27:14 +0000 (18:27 -0500)
committerStéphane Nicolet <cassio@free.fr>
Thu, 21 Feb 2019 18:53:03 +0000 (19:53 +0100)
This is a somewhat different patch. It fixes blindspots for
 two knights vs pawn endgame.

With local testing starting from random KNNvKP positions where the
pawn has not advanced beyond the 4th rank (thanks @protonspring !)
at 15+0.15 (4 cores), this went +105=868-27 against master. All except
two losses were won in reverse.

The heuristic is simple but effective - the strategy in these endgames
is to push the opposing king to the corner, then move the knight that's
blocking the pawn in for the checkmate while the pawn is free to move
and prevents stalemate. This patch gives SF the little boost it needs
to search the relevant king-cornering mating lines.

See the discussion in pull request 1939 for some more good results for
this test in independant tests:
https://github.com/official-stockfish/Stockfish/pull/1939

Bench: 3310239

src/endgame.cpp
src/endgame.h
src/search.cpp

index 835173c468b68bed46b7159dfafe5e32d74c9b0a..3e572205970d63cba9da91421e81bd291cf5e36c 100644 (file)
@@ -286,6 +286,21 @@ Value Endgame<KQKR>::operator()(const Position& pos) const {
 }
 
 
+/// KNN vs KP. Simply push the opposing king to the corner.
+template<>
+Value Endgame<KNNKP>::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<KING>(weakSide)];
+
+    return strongSide == pos.side_to_move() ? result : -result;
+}
+
+
 /// Some cases of trivial draws
 template<> Value Endgame<KNNK>::operator()(const Position&) const { return VALUE_DRAW; }
 
index 941cb31017a6ef0c3d373c9ba17abfea9036dc5d..2a48488fcd8ce2636849cb01b078cfc984e7cb9e 100644 (file)
@@ -37,6 +37,7 @@ enum EndgameCode {
 
   EVALUATION_FUNCTIONS,
   KNNK,  // KNN vs K
+  KNNKP, // KNN vs KP
   KXK,   // Generic "mate lone king" eval
   KBNK,  // KBN vs K
   KPK,   // KP vs K
@@ -125,6 +126,7 @@ public:
     add<KRKN>("KRKN");
     add<KQKP>("KQKP");
     add<KQKR>("KQKR");
+    add<KNNKP>("KNNKP");
 
     add<KNPK>("KNPK");
     add<KNPKB>("KNPKB");
index 6bb1e1dfdbf54c6bbce8f7c9572f58e810403bec..2e7dd6989736fa786c2a0b5ada5d681d35cb7136 100644 (file)
@@ -830,7 +830,7 @@ namespace {
         int probCutCount = 0;
 
         while (  (move = mp.next_move()) != MOVE_NONE
-                && probCutCount < 2 + 2 * cutNode)
+               && probCutCount < 2 + 2 * cutNode)
             if (move != excludedMove && pos.legal(move))
             {
                 probCutCount++;