+/// K and two minors vs K and one or two minors or K and two knights against
+/// king alone are always draw.
+template<>
+Value Endgame<KmmKm>::operator()(const Position&) const {
+ return VALUE_DRAW;
+}
+
+template<>
+Value Endgame<KNNK>::operator()(const Position&) const {
+ return VALUE_DRAW;
+}
+
+/// K, bishop and one or more pawns vs K. It checks for draws with rook pawns and
+/// a bishop of the wrong color. If such a draw is detected, SCALE_FACTOR_DRAW
+/// is returned. If not, the return value is SCALE_FACTOR_NONE, i.e. no scaling
+/// will be used.
+template<>
+ScaleFactor Endgame<KBPsK>::operator()(const Position& pos) const {
+
+ assert(pos.non_pawn_material(strongerSide) == BishopValueMg);
+ assert(pos.piece_count(strongerSide, BISHOP) == 1);
+ assert(pos.piece_count(strongerSide, PAWN) >= 1);
+
+ // No assertions about the material of weakerSide, because we want draws to
+ // be detected even when the weaker side has some pawns.
+
+ Bitboard pawns = pos.pieces(strongerSide, PAWN);
+ File pawnFile = file_of(pos.piece_list(strongerSide, PAWN)[0]);
+
+ // All pawns are on a single rook file ?
+ if ( (pawnFile == FILE_A || pawnFile == FILE_H)
+ && !(pawns & ~file_bb(pawnFile)))
+ {
+ Square bishopSq = pos.piece_list(strongerSide, BISHOP)[0];
+ Square queeningSq = relative_square(strongerSide, pawnFile | RANK_8);
+ Square kingSq = pos.king_square(weakerSide);
+
+ if ( opposite_colors(queeningSq, bishopSq)
+ && abs(file_of(kingSq) - pawnFile) <= 1)
+ {
+ // The bishop has the wrong color, and the defending king is on the
+ // file of the pawn(s) or the adjacent file. Find the rank of the
+ // frontmost pawn.
+ Rank rank;
+ if (strongerSide == WHITE)
+ {
+ for (rank = RANK_7; !(rank_bb(rank) & pawns); rank--) {}
+ assert(rank >= RANK_2 && rank <= RANK_7);
+ }
+ else
+ {
+ for (rank = RANK_2; !(rank_bb(rank) & pawns); rank++) {}
+ rank = Rank(rank ^ 7); // HACK to get the relative rank
+ assert(rank >= RANK_2 && rank <= RANK_7);
+ }
+ // If the defending king has distance 1 to the promotion square or
+ // is placed somewhere in front of the pawn, it's a draw.
+ if ( square_distance(kingSq, queeningSq) <= 1
+ || relative_rank(strongerSide, kingSq) >= rank)
+ return SCALE_FACTOR_DRAW;