From badb2aca44d6507f35dafc8b5c3921a6649a40f8 Mon Sep 17 00:00:00 2001 From: Kurtbusch Date: Fri, 4 Jan 2019 18:27:14 -0500 Subject: [PATCH] Add KNNvKP Endgame Heuristic 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 | 15 +++++++++++++++ src/endgame.h | 2 ++ src/search.cpp | 2 +- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/endgame.cpp b/src/endgame.cpp index 835173c4..3e572205 100644 --- a/src/endgame.cpp +++ b/src/endgame.cpp @@ -286,6 +286,21 @@ Value Endgame::operator()(const Position& pos) const { } +/// KNN vs KP. Simply push the opposing king to the corner. +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)]; + + return strongSide == pos.side_to_move() ? result : -result; +} + + /// Some cases of trivial draws template<> Value Endgame::operator()(const Position&) const { return VALUE_DRAW; } diff --git a/src/endgame.h b/src/endgame.h index 941cb310..2a48488f 100644 --- a/src/endgame.h +++ b/src/endgame.h @@ -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"); add("KQKP"); add("KQKR"); + add("KNNKP"); add("KNPK"); add("KNPKB"); diff --git a/src/search.cpp b/src/search.cpp index 6bb1e1df..2e7dd698 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -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++; -- 2.39.2