Add comments to pos.see_ge()
authorceebo <chricainogithub@gmail.com>
Wed, 8 Nov 2017 17:21:46 +0000 (17:21 +0000)
committerMarco Costalba <mcostalba@users.noreply.github.com>
Fri, 10 Nov 2017 11:14:53 +0000 (12:14 +0100)
In terms of technical changes this patch eliminates the return
statements from the main loop of pos.see_ge() and replaces two conditional
computations with a single bitwise negation.

No functional change

src/position.cpp

index 42c1adff71591a270148adb43b37d2588cd2fe29..14490cdd4729c6a55632e3d3ac861509b779679d 100644 (file)
@@ -1003,17 +1003,21 @@ bool Position::see_ge(Move m, Value threshold) const {
   Value balance; // Values of the pieces taken by us minus opponent's ones
   Bitboard occupied, stmAttackers;
 
   Value balance; // Values of the pieces taken by us minus opponent's ones
   Bitboard occupied, stmAttackers;
 
-  balance = PieceValue[MG][piece_on(to)];
+  // The opponent may be able to recapture so this is the best result
+  // we can hope for.
+  balance = PieceValue[MG][piece_on(to)] - threshold;
 
 
-  if (balance < threshold)
+  if (balance < VALUE_ZERO)
       return false;
 
       return false;
 
+  // Now assume the worst possible result: that the opponent can
+  // capture our piece for free.
   balance -= PieceValue[MG][nextVictim];
 
   balance -= PieceValue[MG][nextVictim];
 
-  if (balance >= threshold) // Always true if nextVictim == KING
+  if (balance >= VALUE_ZERO) // Always true if nextVictim == KING
       return true;
 
       return true;
 
-  bool relativeStm = true; // True if the opponent is to move
+  bool opponentToMove = true;
   occupied = pieces() ^ from ^ to;
 
   // Find all attackers to the destination square, with the moving piece removed,
   occupied = pieces() ^ from ^ to;
 
   // Find all attackers to the destination square, with the moving piece removed,
@@ -1022,6 +1026,12 @@ bool Position::see_ge(Move m, Value threshold) const {
 
   while (true)
   {
 
   while (true)
   {
+      // The balance is negative only because we assumed we could win
+      // the last piece for free. We are truly winning only if we can
+      // win the last piece _cheaply enough_. Test if we can actually
+      // do this otherwise "give up".
+      assert(balance < VALUE_ZERO);
+
       stmAttackers = attackers & pieces(stm);
 
       // Don't allow pinned pieces to attack pieces except the king as long all
       stmAttackers = attackers & pieces(stm);
 
       // Don't allow pinned pieces to attack pieces except the king as long all
@@ -1029,25 +1039,40 @@ bool Position::see_ge(Move m, Value threshold) const {
       if (!(st->pinnersForKing[stm] & ~occupied))
           stmAttackers &= ~st->blockersForKing[stm];
 
       if (!(st->pinnersForKing[stm] & ~occupied))
           stmAttackers &= ~st->blockersForKing[stm];
 
+      // If we have no more attackers we must give up
       if (!stmAttackers)
       if (!stmAttackers)
-          return relativeStm;
+          break;
 
       // Locate and remove the next least valuable attacker
       nextVictim = min_attacker<PAWN>(byTypeBB, to, stmAttackers, occupied, attackers);
 
       if (nextVictim == KING)
 
       // Locate and remove the next least valuable attacker
       nextVictim = min_attacker<PAWN>(byTypeBB, to, stmAttackers, occupied, attackers);
 
       if (nextVictim == KING)
-          return relativeStm == bool(attackers & pieces(~stm));
-
-      balance += relativeStm ?  PieceValue[MG][nextVictim]
-                             : -PieceValue[MG][nextVictim];
+      {
+          // Our only attacker is the king. If the opponent still has
+          // attackers we must give up. Otherwise we make the move and
+          // (having no more attackers) the opponent must give up.
+          if (!(attackers & pieces(~stm)))
+              opponentToMove = !opponentToMove;
+          break;
+      }
 
 
-      relativeStm = !relativeStm;
+      // Assume the opponent can win the next piece for free and switch sides
+      balance += PieceValue[MG][nextVictim];
+      opponentToMove = !opponentToMove;
 
 
-      if (relativeStm == (balance >= threshold))
-          return relativeStm;
+      // If balance is negative after receiving a free piece then give up
+      if (balance < VALUE_ZERO)
+          break;
 
 
+      // Complete the process of switching sides. The first line swaps
+      // all negative numbers with non-negative numbers. The compiler
+      // probably knows that it is just the bitwise negation ~balance.
+      balance = -balance-1;
       stm = ~stm;
   }
       stm = ~stm;
   }
+
+  // If the opponent gave up we win, otherwise we lose.
+  return opponentToMove;
 }
 
 
 }