+ if (relative_rank(strongerSide, psq1) > relative_rank(strongerSide, psq2))
+ {
+ blockSq1 = psq1 + pawn_push(strongerSide);
+ blockSq2 = file_of(psq2) | rank_of(psq1);
+ }
+ else
+ {
+ blockSq1 = psq2 + pawn_push(strongerSide);
+ blockSq2 = file_of(psq1) | rank_of(psq2);
+ }
+
+ switch (file_distance(psq1, psq2))
+ {
+ case 0:
+ // Both pawns are on the same file. Easy draw if defender firmly controls
+ // some square in the frontmost pawn's path.
+ if ( file_of(ksq) == file_of(blockSq1)
+ && relative_rank(strongerSide, ksq) >= relative_rank(strongerSide, blockSq1)
+ && opposite_colors(ksq, wbsq))
+ return SCALE_FACTOR_DRAW;
+ else
+ return SCALE_FACTOR_NONE;
+
+ case 1:
+ // Pawns on adjacent files. Draw if defender firmly controls the square
+ // in front of the frontmost pawn's path, and the square diagonally behind
+ // this square on the file of the other pawn.
+ if ( ksq == blockSq1
+ && opposite_colors(ksq, wbsq)
+ && ( bbsq == blockSq2
+ || (pos.attacks_from<BISHOP>(blockSq2) & pos.pieces(weakerSide, BISHOP))
+ || abs(r1 - r2) >= 2))
+ return SCALE_FACTOR_DRAW;
+
+ else if ( ksq == blockSq2
+ && opposite_colors(ksq, wbsq)
+ && ( bbsq == blockSq1
+ || (pos.attacks_from<BISHOP>(blockSq1) & pos.pieces(weakerSide, BISHOP))))
+ return SCALE_FACTOR_DRAW;
+ else
+ return SCALE_FACTOR_NONE;
+
+ default:
+ // The pawns are not on the same file or adjacent files. No scaling.
+ return SCALE_FACTOR_NONE;
+ }
+}
+
+
+/// K, bisop and a pawn vs K and knight. There is a single rule: 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.
+template<>
+ScaleFactor Endgame<KBPKN>::operator()(const Position& pos) const {
+
+ assert(pos.non_pawn_material(strongerSide) == BishopValueMg);
+ assert(pos.non_pawn_material(weakerSide ) == KnightValueMg);
+ assert(pos.count<BISHOP>(strongerSide) == 1);
+ assert(pos.count<KNIGHT>(weakerSide ) == 1);
+ assert(pos.count< PAWN>(strongerSide) == 1);
+ assert(pos.count< PAWN>(weakerSide ) == 0);
+
+ Square pawnSq = pos.list<PAWN>(strongerSide)[0];
+ Square strongerBishopSq = pos.list<BISHOP>(strongerSide)[0];