I'm adding the pin-aware see improvement to my rewrite of see() and I noticed something which seems interesting. I couldn't get my see() functionally the same, so I decided to print out the positions where mine returns a different result.
Example:
s1 = 0, s2 = 1
+---+---+---+---+---+---+---+---+
| r | | | q | k | | | r |
+---+---+---+---+---+---+---+---+
| p | p | p | b | | p | p | p |
+---+---+---+---+---+---+---+---+
| | | n | p | | | | |
+---+---+---+---+---+---+---+---+
| | B | b | | | | | |
+---+---+---+---+---+---+---+---+
| | | | | n | | | |
+---+---+---+---+---+---+---+---+
| | | | | | N | | |
+---+---+---+---+---+---+---+---+
| P | P | P | | | P | P | P |
+---+---+---+---+---+---+---+---+
| R | N | B | Q | R | | K | |
+---+---+---+---+---+---+---+---+
Fen: r2qk2r/pppb1ppp/2np4/1Bb5/4n3/5N2/PPP2PPP/RNBQR1K1 b kq - 1 1
Key: F88D2602D22EF907
Checkers:
from = 34, to = 13, value = 0
SF's see says Bxf2 has negative see. Mine says it is non-negative (>= value).
I'd say mine is right.
If the capturing piece is a king, I am checking whether the opponent has any attackers left WITHOUT first removing pinned pieces. Here the knight on e4 makes the king capture invalid even though it is pinned.
How about this:
do {
assert(slIndex < 32);
// Add the new entry to the swap list
swapList[slIndex] = -swapList[slIndex - 1] + PieceValue[MG][captured];
// Locate and remove the next least valuable attacker
captured = min_attacker<PAWN>(byTypeBB, to, stmAttackers, occupied, attackers);
stm = ~stm;
stmAttackers = attackers & pieces(stm);
if (captured == KING) // Stop before a king capture
{
slIndex += !stmAttackers;
break;
}
if ( (stmAttackers & pinned_pieces(stm))
&& (st->pinnersForKing[stm] & occupied) == st->pinnersForKing[stm])
stmAttackers &= ~pinned_pieces(stm);
++slIndex;
} while (stmAttackers);
The slIndex += line is cryptic and could use a better comment.
There may be a better way to do this; I just want to point out a possible further improvement.