We do not need to change the winnerKSq variable, so we can simplify
a little bit the logic of the code by changing only the loserKSq
variable when it is necessary. Also consolidate and clarify comments.
See the pull request thread for a proof that the code is correct:
https://github.com/official-stockfish/Stockfish/pull/1854
No functional change
/// Mate with KBN vs K. This is similar to KX vs K, but we have to drive the
/// 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<KBNK>::operator()(const Position& pos) const {
template<>
Value Endgame<KBNK>::operator()(const Position& pos) const {
Square loserKSq = pos.square<KING>(weakSide);
Square bishopSq = pos.square<BISHOP>(strongSide);
Square loserKSq = pos.square<KING>(weakSide);
Square bishopSq = pos.square<BISHOP>(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)]
Value result = VALUE_KNOWN_WIN
+ PushClose[distance(winnerKSq, loserKSq)]
- + PushToCorners[loserKSq];
+ + PushToCorners[opposite_colors(bishopSq, SQ_A1) ? ~loserKSq : loserKSq];
return strongSide == pos.side_to_move() ? result : -result;
}
return strongSide == pos.side_to_move() ? result : -result;
}