Add some knowledge for KRPKB endgame
authorceebo <chricainogithub@gmail.com>
Sun, 13 Oct 2013 20:50:45 +0000 (21:50 +0100)
committerMarco Costalba <mcostalba@gmail.com>
Mon, 14 Oct 2013 05:44:02 +0000 (07:44 +0200)
bench: 8279065

src/endgame.cpp
src/endgame.h

index 75750dd2ba20dc0e2d048f46475814b9e141b5bc..45a04815c42bd4dddf5fa4d23642f0f1193435be 100644 (file)
@@ -102,6 +102,7 @@ Endgames::Endgames() {
   add<KNPK>("KNPK");
   add<KNPKB>("KNPKB");
   add<KRPKR>("KRPKR");
+  add<KRPKB>("KRPKB");
   add<KBPKB>("KBPKB");
   add<KBPKN>("KBPKN");
   add<KBPPKB>("KBPPKB");
@@ -624,6 +625,51 @@ ScaleFactor Endgame<KRPKR>::operator()(const Position& pos) const {
   return SCALE_FACTOR_NONE;
 }
 
+template<>
+ScaleFactor Endgame<KRPKB>::operator()(const Position& pos) const {
+
+  assert(pos.non_pawn_material(strongerSide) == RookValueMg);
+  assert(pos.non_pawn_material(weakerSide) == BishopValueMg);
+  assert(pos.count<PAWN>(strongerSide) == 1);
+  assert(pos.count<PAWN>(weakerSide) == 0);
+
+  // Test for a rook pawn
+  if (pos.pieces(PAWN) & (FileABB | FileHBB))
+  {
+      Square ksq = pos.king_square(weakerSide);
+      Square bsq = pos.list<BISHOP>(weakerSide)[0];
+      Square psq = pos.list<PAWN>(strongerSide)[0];
+      Rank rk = relative_rank(strongerSide, psq);
+      Square push = pawn_push(strongerSide);
+
+      // If the pawn is on the 5th rank and the pawn (currently) is on
+      // the same color square as the bishop then there is a chance of
+      // a fortress. Depending on the king position give a moderate
+      // reduction or a stronger one if the defending king is near the
+      // corner but not trapped there.
+      if (rk == RANK_5 && !opposite_colors(bsq, psq))
+      {
+          int d = square_distance(psq + 3 * push, ksq);
+
+          if (d <= 2 && !(d == 0 && ksq == pos.king_square(strongerSide) + 2 * push))
+              return ScaleFactor(24);
+          else
+              return ScaleFactor(48);
+      }
+
+      // When the pawn has moved to the 6th rank we can be fairly sure
+      // it's drawn if the bishop attacks the square in front of the
+      // pawn from a reasonable distance and the defending king is near
+      // the corner
+      if (   rk == RANK_6
+          && square_distance(psq + 2 * push, ksq) <= 1
+          && (PseudoAttacks[BISHOP][bsq] & (psq + push))
+          && file_distance(bsq, psq) >= 2)
+          return ScaleFactor(8);
+  }
+
+  return SCALE_FACTOR_NONE;
+}
 
 /// K, rook and two pawns vs K, rook and one pawn. There is only a single
 /// pattern: If the stronger side has no passed pawns and the defending king
index 49f39990ba513e6ca8584df55fa9ebadddfe6d9d..bb49b2ff80a5e7ebec59588f2e71ead39743d58c 100644 (file)
@@ -52,6 +52,7 @@ enum EndgameType {
   KBPsK,   // KB+pawns vs K
   KQKRPs,  // KQ vs KR+pawns
   KRPKR,   // KRP vs KR
+  KRPKB,   // KRP vs KB
   KRPPKRP, // KRPP vs KRP
   KPsK,    // King and pawns vs king
   KBPKB,   // KBP vs KB