X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fendgame.cpp;h=5958e633d90e271e9fef852014defd7d6000164b;hb=6373fd56e90bc6114230a70cacad804248d955e2;hp=55a4caba593a43c77bf3d3d2343f239f8b9a0301;hpb=cf5d683408a2ef8a1c80be9bf7d6790a38b16277;p=stockfish
diff --git a/src/endgame.cpp b/src/endgame.cpp
index 55a4caba..5958e633 100644
--- a/src/endgame.cpp
+++ b/src/endgame.cpp
@@ -18,7 +18,6 @@
along with this program. If not, see .
*/
-#include
#include
#include "bitboard.h"
@@ -45,14 +44,14 @@ namespace {
// Table used to drive the king towards a corner square of the
// right color in KBN vs K endgames.
constexpr int PushToCorners[SQUARE_NB] = {
- 200, 190, 180, 170, 160, 150, 140, 130,
- 190, 180, 170, 160, 150, 140, 130, 140,
- 180, 170, 155, 140, 140, 125, 140, 150,
- 170, 160, 140, 120, 110, 140, 150, 160,
- 160, 150, 140, 110, 120, 140, 160, 170,
- 150, 140, 125, 140, 140, 155, 170, 180,
- 140, 130, 140, 150, 160, 170, 180, 190,
- 130, 140, 150, 160, 170, 180, 190, 200
+ 6400, 6080, 5760, 5440, 5120, 4800, 4480, 4160,
+ 6080, 5760, 5440, 5120, 4800, 4480, 4160, 4480,
+ 5760, 5440, 4960, 4480, 4480, 4000, 4480, 4800,
+ 5440, 5120, 4480, 3840, 3520, 4480, 4800, 5120,
+ 5120, 4800, 4480, 3520, 3840, 4480, 5120, 5440,
+ 4800, 4480, 4000, 4480, 4480, 4960, 5440, 5760,
+ 4480, 4160, 4480, 4800, 5120, 5440, 5760, 6080,
+ 4160, 4480, 4800, 5120, 5440, 5760, 6080, 6400
};
// Tables used to drive a piece towards or away from another piece
@@ -77,10 +76,7 @@ namespace {
if (file_of(pos.square(strongSide)) >= FILE_E)
sq = Square(sq ^ 7); // Mirror SQ_H1 -> SQ_A1
- if (strongSide == BLACK)
- sq = ~sq;
-
- return sq;
+ return strongSide == WHITE ? sq : ~sq;
}
} // namespace
@@ -120,7 +116,7 @@ Value Endgame::operator()(const Position& pos) const {
/// Mate with KBN vs K. This is similar to KX vs K, but we have to drive the
-/// defending king towards a corner square of the right color.
+/// defending king towards a corner square that our bishop attacks.
template<>
Value Endgame::operator()(const Position& pos) const {
@@ -131,19 +127,14 @@ Value Endgame::operator()(const Position& pos) const {
Square loserKSq = pos.square(weakSide);
Square bishopSq = pos.square(strongSide);
- // kbnk_mate_table() tries to drive toward corners A1 or H8. If we have a
- // bishop that cannot reach the above squares, we flip the kings in order
- // to drive the enemy toward corners A8 or H1.
- if (opposite_colors(bishopSq, SQ_A1))
- {
- winnerKSq = ~winnerKSq;
- loserKSq = ~loserKSq;
- }
+ // If our Bishop does not attack A1/H8, we flip the enemy king square
+ // to drive to opposite corners (A8/H1).
Value result = VALUE_KNOWN_WIN
+ PushClose[distance(winnerKSq, loserKSq)]
- + PushToCorners[loserKSq];
+ + PushToCorners[opposite_colors(bishopSq, SQ_A1) ? ~loserKSq : loserKSq];
+ assert(abs(result) < VALUE_MATE_IN_MAX_PLY);
return strongSide == pos.side_to_move() ? result : -result;
}
@@ -291,6 +282,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; }
@@ -629,8 +635,6 @@ ScaleFactor Endgame::operator()(const Position& pos) const {
Square ksq = pos.square(weakSide);
Square psq1 = pos.squares(strongSide)[0];
Square psq2 = pos.squares(strongSide)[1];
- Rank r1 = rank_of(psq1);
- Rank r2 = rank_of(psq2);
Square blockSq1, blockSq2;
if (relative_rank(strongSide, psq1) > relative_rank(strongSide, psq2))
@@ -664,7 +668,7 @@ ScaleFactor Endgame::operator()(const Position& pos) const {
&& opposite_colors(ksq, wbsq)
&& ( bbsq == blockSq2
|| (pos.attacks_from(blockSq2) & pos.pieces(weakSide, BISHOP))
- || distance(r1, r2) >= 2))
+ || distance(psq1, psq2) >= 2))
return SCALE_FACTOR_DRAW;
else if ( ksq == blockSq2
@@ -729,6 +733,9 @@ ScaleFactor Endgame::operator()(const Position& pos) const {
template<>
ScaleFactor Endgame::operator()(const Position& pos) const {
+ assert(verify_material(pos, strongSide, KnightValueMg, 1));
+ assert(verify_material(pos, weakSide, BishopValueMg, 0));
+
Square pawnSq = pos.square(strongSide);
Square bishopSq = pos.square(weakSide);
Square weakKingSq = pos.square(weakSide);