- clear_bit(&occ, from);
- attackers = attackers_to(to, occ);
-
- // If the opponent has no attackers we are finished
- stm = flip(color_of(piece_on(from)));
- stmAttackers = attackers & pieces(stm);
- if (!stmAttackers)
- return PieceValueMidgame[capturedType];
-
- // 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.
- swapList[0] = PieceValueMidgame[capturedType];
- capturedType = type_of(piece_on(from));
-
- do {
- // Locate the least valuable attacker for the side to move. The loop
- // below looks like it is potentially infinite, but it isn't. We know
- // that the side to move still has at least one attacker left.
- for (pt = PAWN; !(stmAttackers & pieces(pt)); pt++)
- assert(pt < KING);
-
- // Remove the attacker we just found from the 'occupied' bitboard,
- // and scan for new X-ray attacks behind the attacker.
- b = stmAttackers & pieces(pt);
- occ ^= (b & (~b + 1));
- attackers |= (rook_attacks_bb(to, occ) & pieces(ROOK, QUEEN))
- | (bishop_attacks_bb(to, occ) & pieces(BISHOP, QUEEN));
-
- attackers &= occ; // Cut out pieces we've already done
-
- // Add the new entry to the swap list
- assert(slIndex < 32);
- swapList[slIndex] = -swapList[slIndex - 1] + PieceValueMidgame[capturedType];
- slIndex++;
-
- // Remember the value of the capturing piece, and change the side to
- // move before beginning the next iteration.
- capturedType = pt;
- stm = flip(stm);
- stmAttackers = attackers & pieces(stm);
-
- // Stop before processing a king capture
- if (capturedType == KING && stmAttackers)
- {
- assert(slIndex < 32);
- swapList[slIndex++] = QueenValueMidgame*10;
- break;
- }
- } while (stmAttackers);
-
- // Having built the swap list, we negamax through it to find the best
- // achievable score from the point of view of the side to move.
- while (--slIndex)
- swapList[slIndex-1] = std::min(-swapList[slIndex], swapList[slIndex-1]);