X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fendgame.cpp;h=e10f8d5da975646d236468f6dc251f0052df60bb;hb=0dbc72d82e7f5f314499b22a04dcef45edcdba9a;hp=f65a267d67a4d4f9ae3ac06509280002989cd52c;hpb=027d85e82a0a4bb3210039ae9b60da5bbaff546b;p=stockfish
diff --git a/src/endgame.cpp b/src/endgame.cpp
index f65a267d..e10f8d5d 100644
--- a/src/endgame.cpp
+++ b/src/endgame.cpp
@@ -1,7 +1,8 @@
/*
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
- Copyright (C) 2008-2013 Marco Costalba, Joona Kiiski, Tord Romstad
+ Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
+ Copyright (C) 2015-2019 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
Stockfish is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -17,11 +18,9 @@
along with this program. If not, see .
*/
-#include
#include
#include "bitboard.h"
-#include "bitcount.h"
#include "endgame.h"
#include "movegen.h"
@@ -31,7 +30,7 @@ namespace {
// Table used to drive the king towards the edge of the board
// in KX vs K and KQ vs KR endgames.
- const int PushToEdges[SQUARE_NB] = {
+ constexpr int PushToEdges[SQUARE_NB] = {
100, 90, 80, 70, 70, 80, 90, 100,
90, 70, 60, 50, 50, 60, 70, 90,
80, 60, 40, 30, 30, 40, 60, 80,
@@ -39,153 +38,132 @@ namespace {
70, 50, 30, 20, 20, 30, 50, 70,
80, 60, 40, 30, 30, 40, 60, 80,
90, 70, 60, 50, 50, 60, 70, 90,
- 100, 90, 80, 70, 70, 80, 90, 100,
+ 100, 90, 80, 70, 70, 80, 90, 100
};
// Table used to drive the king towards a corner square of the
// right color in KBN vs K endgames.
- const 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
+ constexpr int PushToCorners[SQUARE_NB] = {
+ 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
- const int PushClose[8] = { 0, 0, 100, 80, 60, 40, 20, 10 };
- const int PushAway [8] = { 0, 5, 20, 40, 60, 80, 90, 100 };
+ constexpr int PushClose[8] = { 0, 0, 100, 80, 60, 40, 20, 10 };
+ constexpr int PushAway [8] = { 0, 5, 20, 40, 60, 80, 90, 100 };
+
+ // Pawn Rank based scaling factors used in KRPPKRP endgame
+ constexpr int KRPPKRPScaleFactors[RANK_NB] = { 0, 9, 10, 14, 21, 44, 0, 0 };
#ifndef NDEBUG
- bool verify_material(const Position& pos, Color c, Value npm, int num_pawns) {
- return pos.non_pawn_material(c) == npm && pos.count(c) == num_pawns;
+ bool verify_material(const Position& pos, Color c, Value npm, int pawnsCnt) {
+ return pos.non_pawn_material(c) == npm && pos.count(c) == pawnsCnt;
}
#endif
- // Get the material key of a Position out of the given endgame key code
- // like "KBPKN". The trick here is to first forge an ad-hoc fen string
- // and then let a Position object to do the work for us. Note that the
- // fen string could correspond to an illegal position.
- Key key(const string& code, Color c) {
-
- assert(code.length() > 0 && code.length() < 8);
- assert(code[0] == 'K');
-
- string sides[] = { code.substr(code.find('K', 1)), // Weaker
- code.substr(0, code.find('K', 1)) }; // Stronger
+ // Map the square as if strongSide is white and strongSide's only pawn
+ // is on the left half of the board.
+ Square normalize(const Position& pos, Color strongSide, Square sq) {
- std::transform(sides[c].begin(), sides[c].end(), sides[c].begin(), tolower);
+ assert(pos.count(strongSide) == 1);
- string fen = sides[0] + char('0' + int(8 - code.length()))
- + sides[1] + "/8/8/8/8/8/8/8 w - - 0 10";
+ if (file_of(pos.square(strongSide)) >= FILE_E)
+ sq = Square(sq ^ 7); // Mirror SQ_H1 -> SQ_A1
- return Position(fen, false, NULL).material_key();
+ return strongSide == WHITE ? sq : ~sq;
}
- template
- void delete_endgame(const typename M::value_type& p) { delete p.second; }
-
} // namespace
-/// Endgames members definitions
-
-Endgames::Endgames() {
-
- add("KPK");
- add("KNNK");
- add("KBNK");
- add("KRKP");
- add("KRKB");
- add("KRKN");
- add("KQKP");
- add("KQKR");
- add("KBBKN");
-
- add("KNPK");
- add("KNPKB");
- add("KRPKR");
- add("KRPKB");
- add("KBPKB");
- add("KBPKN");
- add("KBPPKB");
- add("KRPPKRP");
-}
+namespace Endgames {
-Endgames::~Endgames() {
+ std::pair