X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fposition.cpp;h=1fe723aec461e20a303582484349b9696ca9c552;hp=e759b64242734a66ba22ad078065751f05e91609;hb=dddaeff7d8d4a0c255310d054a53066296e71004;hpb=dcb323bf0dda6277dad18513060cdf78cece47f2 diff --git a/src/position.cpp b/src/position.cpp index e759b642..1fe723ae 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -703,7 +703,7 @@ void Position::do_move(Move m, StateInfo& newSt, Bitboard dcCandidates) { // pointer to point to the new, ready to be updated, state. struct ReducedStateInfo { Key key, pawnKey, materialKey; - int castleRights, rule50; + int castleRights, rule50, pliesFromNull; Square epSquare; Value mgValue, egValue; Value npMaterial[2]; @@ -724,6 +724,7 @@ void Position::do_move(Move m, StateInfo& newSt, Bitboard dcCandidates) { // Increment the 50 moves rule draw counter. Resetting it to zero in the // case of non-reversible moves is taken care of later. st->rule50++; + st->pliesFromNull++; if (move_is_castle(m)) { @@ -838,6 +839,7 @@ void Position::do_move(Move m, StateInfo& newSt, Bitboard dcCandidates) { Square lastPawnSquare = pieceList[us][PAWN][pieceCount[us][PAWN]]; index[lastPawnSquare] = index[to]; pieceList[us][PAWN][index[lastPawnSquare]] = lastPawnSquare; + pieceList[us][PAWN][pieceCount[us][PAWN]] = SQ_NONE; index[to] = pieceCount[us][promotion] - 1; pieceList[us][promotion][index[to]] = to; @@ -943,6 +945,7 @@ void Position::do_capture_move(Bitboard& key, PieceType capture, Color them, Squ Square lastPieceSquare = pieceList[them][capture][pieceCount[them][capture]]; index[lastPieceSquare] = index[capsq]; pieceList[them][capture][index[lastPieceSquare]] = lastPieceSquare; + pieceList[them][capture][pieceCount[them][capture]] = SQ_NONE; // Reset rule 50 counter st->rule50 = 0; @@ -983,17 +986,22 @@ void Position::do_castle_move(Move m) { rto = relative_square(us, SQ_D1); } - // Move the pieces - Bitboard kmove_bb = make_move_bb(kfrom, kto); - do_move_bb(&(byColorBB[us]), kmove_bb); - do_move_bb(&(byTypeBB[KING]), kmove_bb); - do_move_bb(&(byTypeBB[0]), kmove_bb); // HACK: byTypeBB[0] == occupied squares - - Bitboard rmove_bb = make_move_bb(rfrom, rto); - do_move_bb(&(byColorBB[us]), rmove_bb); - do_move_bb(&(byTypeBB[ROOK]), rmove_bb); - do_move_bb(&(byTypeBB[0]), rmove_bb); // HACK: byTypeBB[0] == occupied squares - + // Remove pieces from source squares: + clear_bit(&(byColorBB[us]), kfrom); + clear_bit(&(byTypeBB[KING]), kfrom); + clear_bit(&(byTypeBB[0]), kfrom); // HACK: byTypeBB[0] == occupied squares + clear_bit(&(byColorBB[us]), rfrom); + clear_bit(&(byTypeBB[ROOK]), rfrom); + clear_bit(&(byTypeBB[0]), rfrom); // HACK: byTypeBB[0] == occupied squares + + // Put pieces on destination squares: + set_bit(&(byColorBB[us]), kto); + set_bit(&(byTypeBB[KING]), kto); + set_bit(&(byTypeBB[0]), kto); // HACK: byTypeBB[0] == occupied squares + set_bit(&(byColorBB[us]), rto); + set_bit(&(byTypeBB[ROOK]), rto); + set_bit(&(byTypeBB[0]), rto); // HACK: byTypeBB[0] == occupied squares + // Update board array Piece king = piece_of_color_and_type(us, KING); Piece rook = piece_of_color_and_type(us, ROOK); @@ -1099,10 +1107,12 @@ void Position::undo_move(Move m) { Square lastPromotionSquare = pieceList[us][promotion][pieceCount[us][promotion]]; index[lastPromotionSquare] = index[to]; pieceList[us][promotion][index[lastPromotionSquare]] = lastPromotionSquare; + pieceList[us][promotion][pieceCount[us][promotion]] = SQ_NONE; index[to] = pieceCount[us][PAWN] - 1; pieceList[us][PAWN][index[to]] = to; } + // Put the piece back at the source square Bitboard move_bb = make_move_bb(to, from); do_move_bb(&(byColorBB[us]), move_bb); @@ -1180,17 +1190,22 @@ void Position::undo_castle_move(Move m) { assert(piece_on(kto) == piece_of_color_and_type(us, KING)); assert(piece_on(rto) == piece_of_color_and_type(us, ROOK)); - - // Put the pieces back at the source square - Bitboard kmove_bb = make_move_bb(kto, kfrom); - do_move_bb(&(byColorBB[us]), kmove_bb); - do_move_bb(&(byTypeBB[KING]), kmove_bb); - do_move_bb(&(byTypeBB[0]), kmove_bb); // HACK: byTypeBB[0] == occupied squares - - Bitboard rmove_bb = make_move_bb(rto, rfrom); - do_move_bb(&(byColorBB[us]), rmove_bb); - do_move_bb(&(byTypeBB[ROOK]), rmove_bb); - do_move_bb(&(byTypeBB[0]), rmove_bb); // HACK: byTypeBB[0] == occupied squares + + // Remove pieces from destination squares: + clear_bit(&(byColorBB[us]), kto); + clear_bit(&(byTypeBB[KING]), kto); + clear_bit(&(byTypeBB[0]), kto); // HACK: byTypeBB[0] == occupied squares + clear_bit(&(byColorBB[us]), rto); + clear_bit(&(byTypeBB[ROOK]), rto); + clear_bit(&(byTypeBB[0]), rto); // HACK: byTypeBB[0] == occupied squares + + // Put pieces on source squares: + set_bit(&(byColorBB[us]), kfrom); + set_bit(&(byTypeBB[KING]), kfrom); + set_bit(&(byTypeBB[0]), kfrom); // HACK: byTypeBB[0] == occupied squares + set_bit(&(byColorBB[us]), rfrom); + set_bit(&(byTypeBB[ROOK]), rfrom); + set_bit(&(byTypeBB[0]), rfrom); // HACK: byTypeBB[0] == occupied squares // Update board board[rto] = board[kto] = EMPTY; @@ -1228,6 +1243,7 @@ void Position::do_null_move(StateInfo& backupSt) { backupSt.mgValue = st->mgValue; backupSt.egValue = st->egValue; backupSt.previous = st->previous; + backupSt.pliesFromNull = st->pliesFromNull; st->previous = &backupSt; // Save the current key to the history[] array, in order to be able to @@ -1244,6 +1260,7 @@ void Position::do_null_move(StateInfo& backupSt) { sideToMove = opposite_color(sideToMove); st->epSquare = SQ_NONE; st->rule50++; + st->pliesFromNull = 0; gamePly++; st->mgValue += (sideToMove == WHITE)? TempoValueMidgame : -TempoValueMidgame; @@ -1265,6 +1282,7 @@ void Position::undo_null_move() { st->mgValue = backupSt->mgValue; st->egValue = backupSt->egValue; st->previous = backupSt->previous; + st->pliesFromNull = backupSt->pliesFromNull; // Update the necessary information sideToMove = opposite_color(sideToMove); @@ -1282,13 +1300,13 @@ void Position::undo_null_move() { 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 { @@ -1304,10 +1322,10 @@ 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] = { @@ -1318,8 +1336,10 @@ int Position::see(Square from, Square to) const { 0, 0 }; - Bitboard attackers, stmAttackers, occ, b; + 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)); @@ -1330,10 +1350,27 @@ int Position::see(Square from, Square to) const { // Initialize pieces Piece piece = piece_on(from); Piece capture = piece_on(to); + Bitboard occ = occupied_squares(); - // Find all attackers to the destination square, with the moving piece - // removed, but possibly an X-ray attacker added behind it. - 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(to, us) & pieces(PAWN, them))) + return -(pieceDiff - seeValues[PAWN] / 2); + + if ( pieceDiff > seeValues[KNIGHT] + && pieces(KNIGHT, them) + &&(pieces(KNIGHT, them) & attacks_from(to))) + return -(pieceDiff - seeValues[KNIGHT] / 2); + } // Handle en passant moves if (st->epSquare == to && type_of_piece_on(from) == PAWN) @@ -1350,6 +1387,8 @@ int Position::see(Square from, Square to) const { 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)) @@ -1403,6 +1442,15 @@ int Position::see(Square from, Square to) const { 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); @@ -1471,8 +1519,8 @@ void Position::clear() { 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; @@ -1670,7 +1718,7 @@ bool Position::is_draw() const { return true; // Draw by repetition? - for (int i = 2; i < Min(gamePly, st->rule50); i += 2) + for (int i = 2; i < Min(Min(gamePly, st->rule50), st->pliesFromNull); i += 2) if (history[gamePly - i] == st->key) return true;