int Position::see(Square to) const {
assert(square_is_ok(to));
- return see(SQ_NONE, to);
+ return see(SQ_NONE, to, false);
}
int Position::see(Move m) const {
assert(move_is_ok(m));
- return see(move_from(m), move_to(m));
+ return see(move_from(m), move_to(m), false);
}
int Position::see_sign(Move m) const {
&& type_of_piece_on(from) != KING)
return 1;
- return see(from, to);
+ return see(from, to, true);
}
-int Position::see(Square from, Square to) const {
+int Position::see(Square from, Square to, bool shortcut) const {
// Material values
static const int seeValues[18] = {
};
Bitboard attackers, stmAttackers, b;
+ int pieceDiff = 0;
+ assert(!shortcut || from != SQ_NONE);
assert(square_is_ok(from) || from == SQ_NONE);
assert(square_is_ok(to));
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
+ // when captured piece value does not compensate the lost of capturing one.
+ if (shortcut)
+ {
+ pieceDiff = seeValues[piece] - seeValues[capture];
+
+ if ( pieceDiff > seeValues[PAWN]
+ &&(attacks_from<PAWN>(to, us) & pieces(PAWN, them)))
+ return -(pieceDiff - seeValues[PAWN] / 2);
+
+ if ( pieceDiff > seeValues[KNIGHT]
+ && pieces(KNIGHT, them)
+ &&(pieces(KNIGHT, them) & attacks_from<KNIGHT>(to)))
+ return -(pieceDiff - seeValues[KNIGHT] / 2);
+ }
+
// Handle en passant moves
if (st->epSquare == to && type_of_piece_on(from) == PAWN)
{
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);
for (int i = 0; i < 64; i++)
board[i] = EMPTY;
- for (int i = 0; i < 7; i++)
- for (int j = 0; j < 8; j++)
+ for (int i = 0; i < 8; i++)
+ for (int j = 0; j < 16; j++)
pieceList[0][i][j] = pieceList[1][i][j] = SQ_NONE;
sideToMove = WHITE;