Stockfish, a UCI chess playing engine derived from Glaurung 2.1
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
- Copyright (C) 2015-2019 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
+ Copyright (C) 2015-2020 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
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <algorithm>
#include <cassert>
#include "bitboard.h"
assert(pos.count<PAWN>(strongSide) == 1);
if (file_of(pos.square<PAWN>(strongSide)) >= FILE_E)
- sq = Square(sq ^ 7); // Mirror SQ_H1 -> SQ_A1
+ sq = Square(int(sq) ^ 7); // Mirror SQ_H1 -> SQ_A1
- if (strongSide == BLACK)
- sq = ~sq;
-
- return sq;
+ return strongSide == WHITE ? sq : ~sq;
}
} // namespace
+namespace Endgames {
+
+ std::pair<Map<Value>, Map<ScaleFactor>> maps;
+
+ void init() {
+
+ add<KPK>("KPK");
+ add<KNNK>("KNNK");
+ add<KBNK>("KBNK");
+ add<KRKP>("KRKP");
+ add<KRKB>("KRKB");
+ add<KRKN>("KRKN");
+ add<KQKP>("KQKP");
+ add<KQKR>("KQKR");
+ add<KNNKP>("KNNKP");
+
+ add<KNPK>("KNPK");
+ add<KNPKB>("KNPKB");
+ add<KRPKR>("KRPKR");
+ add<KRPKB>("KRPKB");
+ add<KBPKB>("KBPKB");
+ add<KBPKN>("KBPKN");
+ add<KBPPKB>("KBPPKB");
+ add<KRPPKRP>("KRPPKRP");
+ }
+}
+
+
/// Mate with KX vs K. This function is used to evaluate positions with
/// king and plenty of material vs a lone king. It simply gives the
/// attacking side a bonus for driving the defending king towards the edge
Square loserKSq = pos.square<KING>(weakSide);
Square bishopSq = pos.square<BISHOP>(strongSide);
- // If our Bishop does not attack A1/H8, we flip the enemy king square
+ // 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
}
-/// KP vs K. This endgame is evaluated with the help of a bitbase.
+/// KP vs K. This endgame is evaluated with the help of a bitbase
template<>
Value Endgame<KPK>::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; }
&& pos.count<PAWN>(weakSide) >= 1)
{
// Get weakSide pawn that is closest to the home rank
- Square weakPawnSq = backmost_sq(weakSide, pos.pieces(weakSide, PAWN));
+ Square weakPawnSq = frontmost_sq(strongSide, pos.pieces(weakSide, PAWN));
Square strongKingSq = pos.square<KING>(strongSide);
Square weakKingSq = pos.square<KING>(weakSide);
Square ksq = pos.square<KING>(weakSide);
Square psq1 = pos.squares<PAWN>(strongSide)[0];
Square psq2 = pos.squares<PAWN>(strongSide)[1];
- Rank r1 = rank_of(psq1);
- Rank r2 = rank_of(psq2);
Square blockSq1, blockSq2;
if (relative_rank(strongSide, psq1) > relative_rank(strongSide, psq2))
&& opposite_colors(ksq, wbsq)
&& ( bbsq == blockSq2
|| (pos.attacks_from<BISHOP>(blockSq2) & pos.pieces(weakSide, BISHOP))
- || distance(r1, r2) >= 2))
+ || distance<Rank>(psq1, psq2) >= 2))
return SCALE_FACTOR_DRAW;
else if ( ksq == blockSq2
template<>
ScaleFactor Endgame<KNPKB>::operator()(const Position& pos) const {
+ assert(verify_material(pos, strongSide, KnightValueMg, 1));
+ assert(verify_material(pos, weakSide, BishopValueMg, 0));
+
Square pawnSq = pos.square<PAWN>(strongSide);
Square bishopSq = pos.square<BISHOP>(weakSide);
Square weakKingSq = pos.square<KING>(weakSide);