Simplify pinners conditions in SEE()
authorSt├ęphane Nicolet <cassio@free.fr>
Wed, 21 Sep 2016 07:32:00 +0000 (09:32 +0200)
committerMarco Costalba <mcostalba@gmail.com>
Thu, 22 Sep 2016 06:31:23 +0000 (08:31 +0200)
Use the following transformations:

- to check that A is included in B, testing "(A & ~B) == 0" is faster
than "(A & B) == A"

- to remove the intersection of A and B from A, doing "A &= ~B;" is as
fast as "if (A & B) A &= ~B;" but is simpler.

Overall, the simpler patch version is 0.3% than current master.

No functional change.

src/position.cpp

index f5081bd..9fe5f89 100644 (file)
@@ -1010,11 +1010,9 @@ Value Position::see(Move m) const {
   occupied ^= to; // For the case when captured piece is a pinner
 
   // Don't allow pinned pieces to attack pieces except the king as long all
-  // pinners are on their original square. When a pinner moves to the
-  // exchange-square or get captured on it, we fall back to standard SEE behaviour.
-  if (   (stmAttackers & pinned_pieces(stm))
-      && (st->pinnersForKing[stm] & occupied) == st->pinnersForKing[stm])
-      stmAttackers &= ~pinned_pieces(stm);
+  // pinners are on their original square.
+  if (!(st->pinnersForKing[stm] & ~occupied))
+      stmAttackers &= ~st->blockersForKing[stm];
 
   if (!stmAttackers)
         return swapList[0];
@@ -1037,10 +1035,11 @@ Value Position::see(Move m) const {
       nextVictim = min_attacker<PAWN>(byTypeBB, to, stmAttackers, occupied, attackers);
       stm = ~stm;
       stmAttackers = attackers & pieces(stm);
-      if (    nextVictim != KING
-          && (stmAttackers & pinned_pieces(stm))
-          && (st->pinnersForKing[stm] & occupied) == st->pinnersForKing[stm])
-          stmAttackers &= ~pinned_pieces(stm);
+
+      // Don't allow pinned pieces to attack pieces except the king
+      if (   nextVictim != KING
+          && !(st->pinnersForKing[stm] & ~occupied))
+          stmAttackers &= ~st->blockersForKing[stm];
 
       ++slIndex;