- // Initialize colors:
- us = this->color_of_piece_on(from);
- them = opposite_color(us);
-
- // Initialize pieces:
- piece = this->piece_on(from);
- capture = this->piece_on(to);
-
- // Find all attackers to the destination square, with the moving piece
- // removed, but possibly an X-ray attacker added behind it:
- occ = this->occupied_squares();
- clear_bit(&occ, from);
- attackers =
- (rook_attacks_bb(to, occ) & this->rooks_and_queens()) |
- (bishop_attacks_bb(to, occ) & this->bishops_and_queens()) |
- (this->knight_attacks(to) & this->knights()) |
- (this->king_attacks(to) & this->kings()) |
- (this->white_pawn_attacks(to) & this->pawns(BLACK)) |
- (this->black_pawn_attacks(to) & this->pawns(WHITE));
- attackers &= occ;
-
- // If the opponent has no attackers, we are finished:
- if((attackers & this->pieces_of_color(them)) == EmptyBoardBB)
- return seeValues[capture];
+ // Initialize colors
+ Color us = (from != SQ_NONE ? color_of_piece_on(from) : opposite_color(color_of_piece_on(to)));
+ Color them = opposite_color(us);
+
+ // Initialize pieces
+ Piece piece = piece_on(from);
+ Piece capture = piece_on(to);
+ Bitboard occ = occupied_squares();
+
+ // King cannot be recaptured
+ if (type_of_piece(piece) == KING)
+ return seeValues[capture];
+
+ // Handle en passant moves
+ if (st->epSquare == to && type_of_piece_on(from) == PAWN)
+ {
+ assert(capture == EMPTY);
+
+ Square capQq = (side_to_move() == WHITE)? (to - DELTA_N) : (to - DELTA_S);
+ capture = piece_on(capQq);
+ assert(type_of_piece_on(capQq) == PAWN);
+
+ // Remove the captured pawn
+ clear_bit(&occ, capQq);
+ }
+
+ while (true)
+ {
+ // Find all attackers to the destination square, with the moving piece
+ // removed, but possibly an X-ray attacker added behind it.
+ clear_bit(&occ, from);
+ attackers = (rook_attacks_bb(to, occ) & pieces(ROOK, QUEEN))
+ | (bishop_attacks_bb(to, occ) & pieces(BISHOP, QUEEN))
+ | (attacks_from<KNIGHT>(to) & pieces(KNIGHT))
+ | (attacks_from<KING>(to) & pieces(KING))
+ | (attacks_from<PAWN>(to, WHITE) & pieces(PAWN, BLACK))
+ | (attacks_from<PAWN>(to, BLACK) & pieces(PAWN, WHITE));
+
+ if (from != SQ_NONE)
+ break;
+
+ // If we don't have any attacker we are finished
+ if ((attackers & pieces_of_color(us)) == EmptyBoardBB)
+ return 0;
+
+ // Locate the least valuable attacker to the destination square
+ // and use it to initialize from square.
+ stmAttackers = attackers & pieces_of_color(us);
+ PieceType pt;
+ for (pt = PAWN; !(stmAttackers & pieces(pt)); pt++)
+ assert(pt < KING);
+
+ from = first_1(stmAttackers & pieces(pt));
+ piece = piece_on(from);
+ }
+
+ // If the opponent has no attackers we are finished
+ stmAttackers = attackers & pieces_of_color(them);
+ if (!stmAttackers)
+ return seeValues[capture];
+
+ attackers &= occ; // Remove the moving piece