This is the most compact and neatest version
is was able to produce.
On normal builds I have a small slowdown:
normal builds base vs. simplification (gcc 4.8.1 Win7-64 i7-3770 @ 3.4GHz x86-64-modern)
Results for 20 tests for each version:
Base Test Diff
Mean
1974744 1969333 5411
StDev 11825 10281 5874
p-value: 0,178
speedup: -0,003
On pgo-builds however I measure a nice 1.1% speedup
pgo-builds base vs. simplification
Results for 20 tests for each version:
Base Test Diff
Mean
1974119 1995444 -21325
StDev 8703 5717 4623
p-value: 1
speedup: 0,011
No functional change.
// If the opponent has no attackers we are finished
stm = ~stm;
stmAttackers = attackers & pieces(stm);
// If the opponent has no attackers we are finished
stm = ~stm;
stmAttackers = attackers & pieces(stm);
- if (!stmAttackers)
- return swapList[0];
+ occupied ^= to; // For the case when captured piece is a pinner
// Don't allow pinned pieces to attack as long all pinners (this includes also
// potential ones) 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.
// Don't allow pinned pieces to attack as long all pinners (this includes also
// potential ones) 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.
- else if ( (stmAttackers & st->blockersForKing[stm])
- && ((st->pinnersForKing[stm] & (occupied ^ (occupied & to))) == st->pinnersForKing[stm]))
- {
- // Pinned pieces can't attack so remove them from attackers
- stmAttackers ^= (stmAttackers & st->blockersForKing[stm]);
- if (!stmAttackers)
- return swapList[0];
- }
+ if ( (stmAttackers & pinned_pieces(stm))
+ && (st->pinnersForKing[stm] & occupied) == st->pinnersForKing[stm])
+ stmAttackers &= ~pinned_pieces(stm);
+
+ if (!stmAttackers)
+ return swapList[0];
// The destination square is defended, which makes things rather more
// difficult to compute. We proceed by building up a "swap list" containing
// The destination square is defended, which makes things rather more
// difficult to compute. We proceed by building up a "swap list" containing
captured = min_attacker<PAWN>(byTypeBB, to, stmAttackers, occupied, attackers);
stm = ~stm;
stmAttackers = attackers & pieces(stm);
captured = min_attacker<PAWN>(byTypeBB, to, stmAttackers, occupied, attackers);
stm = ~stm;
stmAttackers = attackers & pieces(stm);
- if ( stmAttackers
- && (stmAttackers & st->blockersForKing[stm])
- && ((st->pinnersForKing[stm] & (occupied ^ (occupied & to))) == st->pinnersForKing[stm]))
- stmAttackers ^= (stmAttackers & st->blockersForKing[stm]);
+ if ( (stmAttackers & pinned_pieces(stm))
+ && (st->pinnersForKing[stm] & occupied) == st->pinnersForKing[stm])
+ stmAttackers &= ~pinned_pieces(stm);