// Get the material key of Position out of the given endgame key code
// like "KBPKN". The trick here is to first forge an ad-hoc FEN string
// Get the material key of Position out of the given endgame key code
// like "KBPKN". The trick here is to first forge an ad-hoc FEN string
Key key(const string& code, Color c) {
assert(code.length() > 0 && code.length() < 8);
Key key(const string& code, Color c) {
assert(code.length() > 0 && code.length() < 8);
std::transform(sides[c].begin(), sides[c].end(), sides[c].begin(), tolower);
std::transform(sides[c].begin(), sides[c].end(), sides[c].begin(), tolower);
- string fen = sides[0] + char('0' + int(8 - code.length()))
- + sides[1] + "/8/8/8/8/8/8/8 w - - 0 10";
+ string fen = sides[0] + char(8 - sides[0].length() + '0') + "/8/8/8/8/8/8/"
+ + sides[1] + char(8 - sides[1].length() + '0') + " w - - 0 10";
Square rsq = relative_square(strongSide, pos.list<ROOK>(strongSide)[0]);
Square psq = relative_square(strongSide, pos.list<PAWN>(weakSide)[0]);
Square rsq = relative_square(strongSide, pos.list<ROOK>(strongSide)[0]);
Square psq = relative_square(strongSide, pos.list<PAWN>(weakSide)[0]);
Value result;
// If the stronger side's king is in front of the pawn, it's a win
if (wksq < psq && file_of(wksq) == file_of(psq))
Value result;
// If the stronger side's king is in front of the pawn, it's a win
if (wksq < psq && file_of(wksq) == file_of(psq))
// If the weaker side's king is too far from the pawn and the rook,
// it's a win.
else if ( square_distance(bksq, psq) >= 3 + (pos.side_to_move() == weakSide)
&& square_distance(bksq, rsq) >= 3)
// If the weaker side's king is too far from the pawn and the rook,
// it's a win.
else if ( square_distance(bksq, psq) >= 3 + (pos.side_to_move() == weakSide)
&& square_distance(bksq, rsq) >= 3)
// If the pawn is far advanced and supported by the defending king,
// the position is drawish
// If the pawn is far advanced and supported by the defending king,
// the position is drawish
&& square_distance(bksq, psq) == 1
&& rank_of(wksq) >= RANK_4
&& square_distance(wksq, psq) > 2 + (pos.side_to_move() == strongSide))
&& square_distance(bksq, psq) == 1
&& rank_of(wksq) >= RANK_4
&& square_distance(wksq, psq) > 2 + (pos.side_to_move() == strongSide))
- result = Value(200)
- - Value(square_distance(wksq, psq + DELTA_S) * 8)
- + Value(square_distance(bksq, psq + DELTA_S) * 8)
- + Value(square_distance(psq, queeningSq) * 8);
+ result = Value(200) - 8 * ( square_distance(wksq, psq + DELTA_S)
+ - square_distance(bksq, psq + DELTA_S)
+ - square_distance(psq, queeningSq));
/// Some cases of trivial draws
template<> Value Endgame<KNNK>::operator()(const Position&) const { return VALUE_DRAW; }
/// Some cases of trivial draws
template<> Value Endgame<KNNK>::operator()(const Position&) const { return VALUE_DRAW; }
Square kingSq = pos.king_square(weakSide);
if ( opposite_colors(queeningSq, bishopSq)
Square kingSq = pos.king_square(weakSide);
if ( opposite_colors(queeningSq, bishopSq)
int tempo = (pos.side_to_move() == strongSide);
// If the pawn is not too far advanced and the defending king defends the
int tempo = (pos.side_to_move() == strongSide);
// If the pawn is not too far advanced and the defending king defends the
if (relative_rank(strongSide, psq1) > relative_rank(strongSide, psq2))
{
blockSq1 = psq1 + pawn_push(strongSide);
if (relative_rank(strongSide, psq1) > relative_rank(strongSide, psq2))
{
blockSq1 = psq1 + pawn_push(strongSide);