- // Find all attackers to the destination square, with the moving piece
- // removed, but possibly an X-ray attacker added behind it.
- attackers = attackers_to(to, occupied) & occupied;
-
- // If the opponent has no attackers we are finished
- stm = ~stm;
- stmAttackers = attackers & pieces(stm);
- 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);
-
- 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 material gain or loss at each stop in a sequence of captures to the
- // destination square, where the sides alternately capture, and always
- // capture with the least valuable piece. After each capture, we look for
- // new X-ray attacks from behind the capturing piece.
- nextVictim = type_of(piece_on(from));
-
- do {
- assert(slIndex < 32);
-
- // Add the new entry to the swap list
- swapList[slIndex] = -swapList[slIndex - 1] + PieceValue[MG][nextVictim];
-
- // Locate and remove the next least valuable attacker
- 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);
+ if (!stmAttackers)
+ break;
+
+ res ^= 1;
+
+ // Locate and remove the next least valuable attacker, and add to
+ // the bitboard 'attackers' any X-ray attackers behind it.
+ if ((bb = stmAttackers & pieces(PAWN)))
+ {
+ if ((swap = PawnValueMg - swap) < res)
+ break;
+
+ occupied ^= lsb(bb);
+ attackers |= attacks_bb<BISHOP>(to, occupied) & pieces(BISHOP, QUEEN);
+ }
+
+ else if ((bb = stmAttackers & pieces(KNIGHT)))
+ {
+ if ((swap = KnightValueMg - swap) < res)
+ break;
+
+ occupied ^= lsb(bb);
+ }