+ // If all pawns are ahead of the king, on a single rook file and
+ // the king is within one file of the pawns, it's a draw.
+ if ( !(pawns & ~in_front_bb(weakSide, rank_of(ksq)))
+ && !((pawns & ~FileABB) && (pawns & ~FileHBB))
+ && distance<File>(ksq, psq) <= 1)
+ return SCALE_FACTOR_DRAW;
+
+ return SCALE_FACTOR_NONE;
+}
+
+
+/// KBP vs KB. There are two rules: if the defending king is somewhere along the
+/// path of the pawn, and the square of the king is not of the same color as the
+/// stronger side's bishop, it's a draw. If the two bishops have opposite color,
+/// it's almost always a draw.
+template<>
+ScaleFactor Endgame<KBPKB>::operator()(const Position& pos) const {
+
+ assert(verify_material(pos, strongSide, BishopValueMg, 1));
+ assert(verify_material(pos, weakSide, BishopValueMg, 0));
+
+ Square pawnSq = pos.list<PAWN>(strongSide)[0];
+ Square strongBishopSq = pos.list<BISHOP>(strongSide)[0];
+ Square weakBishopSq = pos.list<BISHOP>(weakSide)[0];
+ Square weakKingSq = pos.king_square(weakSide);
+
+ // Case 1: Defending king blocks the pawn, and cannot be driven away
+ if ( file_of(weakKingSq) == file_of(pawnSq)
+ && relative_rank(strongSide, pawnSq) < relative_rank(strongSide, weakKingSq)
+ && ( opposite_colors(weakKingSq, strongBishopSq)
+ || relative_rank(strongSide, weakKingSq) <= RANK_6))
+ return SCALE_FACTOR_DRAW;
+
+ // Case 2: Opposite colored bishops
+ if (opposite_colors(strongBishopSq, weakBishopSq))
+ {
+ // We assume that the position is drawn in the following three situations:
+ //
+ // a. The pawn is on rank 5 or further back.
+ // b. The defending king is somewhere in the pawn's path.
+ // c. The defending bishop attacks some square along the pawn's path,
+ // and is at least three squares away from the pawn.
+ //
+ // These rules are probably not perfect, but in practice they work
+ // reasonably well.
+
+ if (relative_rank(strongSide, pawnSq) <= RANK_5)
+ return SCALE_FACTOR_DRAW;
+ else
+ {
+ Bitboard path = forward_bb(strongSide, pawnSq);
+
+ if (path & pos.pieces(weakSide, KING))
+ return SCALE_FACTOR_DRAW;
+
+ if ( (pos.attacks_from<BISHOP>(weakBishopSq) & path)
+ && distance(weakBishopSq, pawnSq) >= 3)
+ return SCALE_FACTOR_DRAW;
+ }