Permalink
Browse files

Detect drawish KQKP endings

Based off of the rules from the wikipedia page,
here: http://en.wikipedia.org/wiki/Queen_versus_pawn_endgame.

bench does not change: 5312693 but patch is real, has been
tested on specific positions.
  • Loading branch information...
glinscott authored and mcostalba committed Oct 28, 2012
1 parent b3d0302 commit cee6336515d5772370d061aa54cf3ec9f9a0d3c2
Showing with 35 additions and 2 deletions.
  1. +34 −2 src/endgame.cpp
  2. +1 −0 src/endgame.h
View
@@ -95,6 +95,7 @@ Endgames::Endgames() {
add<KRKP>("KRKP");
add<KRKB>("KRKB");
add<KRKN>("KRKN");
+ add<KQKP>("KQKP");
add<KQKR>("KQKR");
add<KBBKN>("KBBKN");
@@ -169,12 +170,12 @@ Value Endgame<KBNK>::operator()(const Position& pos) const {
Square winnerKSq = pos.king_square(strongerSide);
Square loserKSq = pos.king_square(weakerSide);
- Square bishopSquare = pos.piece_list(strongerSide, BISHOP)[0];
+ Square bishopSq = pos.piece_list(strongerSide, BISHOP)[0];
// kbnk_mate_table() tries to drive toward corners A1 or H8,
// if we have a bishop that cannot reach the above squares we
// mirror the kings so to drive enemy toward corners A8 or H1.
- if (opposite_colors(bishopSquare, SQ_A1))
+ if (opposite_colors(bishopSq, SQ_A1))
{
winnerKSq = mirror(winnerKSq);
loserKSq = mirror(loserKSq);
@@ -326,6 +327,37 @@ Value Endgame<KRKN>::operator()(const Position& pos) const {
}
+/// KQ vs KP. In general, a win for the stronger side, however, there are a few
+/// important exceptions. Pawn on 7th rank, A,C,F or H file, with king next can
+/// be a draw, so we scale down to distance between kings only.
+template<>
+Value Endgame<KQKP>::operator()(const Position& pos) const {
+
+ assert(pos.non_pawn_material(strongerSide) == QueenValueMg);
+ assert(pos.piece_count(strongerSide, PAWN) == 0);
+ assert(pos.non_pawn_material(weakerSide) == 0);
+ assert(pos.piece_count(weakerSide, PAWN) == 1);
+
+ Square winnerKSq = pos.king_square(strongerSide);
+ Square loserKSq = pos.king_square(weakerSide);
+ Square pawnSq = pos.piece_list(weakerSide, PAWN)[0];
+
+ Value result = QueenValueEg
+ - PawnValueEg
+ + DistanceBonus[square_distance(winnerKSq, loserKSq)];
+
+ if ( square_distance(loserKSq, pawnSq) == 1
+ && relative_rank(weakerSide, pawnSq) == RANK_7)
+ {
+ File f = file_of(pawnSq);
+
+ if (f == FILE_A || f == FILE_C || f == FILE_F || f == FILE_H)
+ result = Value(DistanceBonus[square_distance(winnerKSq, loserKSq)]);
+ }
+ return strongerSide == pos.side_to_move() ? result : -result;
+}
+
+
/// KQ vs KR. This is almost identical to KX vs K: We give the attacking
/// king a bonus for having the kings close together, and for forcing the
/// defending king towards the edge. If we also take care to avoid null move
View
@@ -39,6 +39,7 @@ enum EndgameType {
KRKP, // KR vs KP
KRKB, // KR vs KB
KRKN, // KR vs KN
+ KQKP, // KQ vs KP
KQKR, // KQ vs KR
KBBKN, // KBB vs KN
KNNK, // KNN vs K

0 comments on commit cee6336

Please sign in to comment.