-
- // Find all attackers to the destination square, with the moving piece
- // removed, but possibly an X-ray attacker added behind it.
- occ ^= from;
- attackers = attackers_to(to, occ);
-
- // If the opponent has no attackers we are finished
- stm = ~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 = ~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]);
-
- return swapList[0];
-}
-
-
-/// Position::clear() erases the position object to a pristine state, with an
-/// empty board, white to move, and no castling rights.
-
-void Position::clear() {
-
- st = &startState;
- memset(st, 0, sizeof(StateInfo));
- st->epSquare = SQ_NONE;
-
- memset(byColorBB, 0, sizeof(Bitboard) * 2);
- memset(byTypeBB, 0, sizeof(Bitboard) * 8);
- memset(pieceCount, 0, sizeof(int) * 2 * 8);
- memset(index, 0, sizeof(int) * 64);
-
- for (int i = 0; i < 8; i++)
- for (int j = 0; j < 16; j++)
- pieceList[0][i][j] = pieceList[1][i][j] = SQ_NONE;
-
- for (Square sq = SQ_A1; sq <= SQ_H8; sq++)