Because we only generate legal moves we can assume
a king cannot be recaptured, so we can safely return
immediately with the captured piece score. If the move
turns out to be illegal it will be pruned anyhow,
independently from SEE value. This gives a good speed up
especially now that we SEE-test all the evasions that
are always legal and very often are king moves.
Another optimization catches almost 15% of cases, unfortunatly
we have already calculated the very expensive attacks, so
benefits are not so big anyway.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
};
Bitboard attackers, stmAttackers, b;
};
Bitboard attackers, stmAttackers, b;
assert(!shortcut || from != SQ_NONE);
assert(square_is_ok(from) || from == SQ_NONE);
assert(!shortcut || from != SQ_NONE);
assert(square_is_ok(from) || from == SQ_NONE);
Piece capture = piece_on(to);
Bitboard occ = occupied_squares();
Piece capture = piece_on(to);
Bitboard occ = occupied_squares();
+ // King cannot be recaptured
+ if (type_of_piece(piece) == KING)
+ return seeValues[capture];
+
// If captured piece is defended by enemy pawns or knights then SEE is negative
// If captured piece is defended by enemy pawns or knights then SEE is negative
- // when captured piece value is not enough to compensate the lost of capturing one.
+ // when captured piece value does not compensate the lost of capturing one.
- int diff = seeValues[piece] - seeValues[capture];
+ pieceDiff = seeValues[piece] - seeValues[capture];
- if ( diff > seeValues[PAWN]
+ if ( pieceDiff > seeValues[PAWN]
&&(attacks_from<PAWN>(to, us) & pieces(PAWN, them)))
&&(attacks_from<PAWN>(to, us) & pieces(PAWN, them)))
- return -(diff - seeValues[PAWN] / 2);
+ return -(pieceDiff - seeValues[PAWN] / 2);
- if ( diff > seeValues[KNIGHT]
+ if ( pieceDiff > seeValues[KNIGHT]
&& pieces(KNIGHT, them)
&&(pieces(KNIGHT, them) & attacks_from<KNIGHT>(to)))
&& pieces(KNIGHT, them)
&&(pieces(KNIGHT, them) & attacks_from<KNIGHT>(to)))
- return -(diff - seeValues[KNIGHT] / 2);
+ return -(pieceDiff - seeValues[KNIGHT] / 2);
}
// Handle en passant moves
}
// Handle en passant moves
for (pt = PAWN; !(stmAttackers & pieces(pt)); pt++)
assert(pt < KING);
for (pt = PAWN; !(stmAttackers & pieces(pt)); pt++)
assert(pt < KING);
+ // If captured piece is defended by an enemy piece then SEE is negative
+ // if captured piece value does not compensate the lost of capturing one.
+ if (pieceDiff > seeValues[pt])
+ {
+ assert(shortcut);
+ return -(pieceDiff - seeValues[pt] / 2);
+ } else
+ pieceDiff = 0; // Only first cycle
+
// Remove the attacker we just found from the 'attackers' bitboard,
// and scan for new X-ray attacks behind the attacker.
b = stmAttackers & pieces(pt);
// Remove the attacker we just found from the 'attackers' bitboard,
// and scan for new X-ray attacks behind the attacker.
b = stmAttackers & pieces(pt);