Simplify pinners conditions in SEE()

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.
This commit is contained in:
Stéphane Nicolet
2016-09-21 09:32:00 +02:00
committed by Marco Costalba
parent 943ae89be1
commit 28240d375c

View 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);
// Don't allow pinned pieces to attack pieces except the king
if ( nextVictim != KING
&& (stmAttackers & pinned_pieces(stm))
&& (st->pinnersForKing[stm] & occupied) == st->pinnersForKing[stm])
stmAttackers &= ~pinned_pieces(stm);
&& !(st->pinnersForKing[stm] & ~occupied))
stmAttackers &= ~st->blockersForKing[stm];
++slIndex;