X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fposition.cpp;h=1fe723aec461e20a303582484349b9696ca9c552;hp=1725acbb4bc76ef68cb91249b76e0d9fa9beec98;hb=dddaeff7d8d4a0c255310d054a53066296e71004;hpb=46141b078cd9df291ad21dbf9b420cb92e9c44ed diff --git a/src/position.cpp b/src/position.cpp index 1725acbb..1fe723ae 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -703,8 +703,8 @@ 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; - Square kingSquare[2], epSquare; + 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)) { @@ -784,10 +785,6 @@ void Position::do_move(Move m, StateInfo& newSt, Bitboard dcCandidates) { board[to] = board[from]; board[from] = EMPTY; - // If the moving piece was a king, update the king square - if (pt == KING) - st->kingSquare[us] = to; - // Update piece lists, note that index[from] is not updated and // becomes stale. This works as long as index[] is accessed just // by known occupied squares. @@ -842,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; @@ -947,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; @@ -987,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); @@ -1005,9 +1009,6 @@ void Position::do_castle_move(Move m) { board[kto] = king; board[rto] = rook; - // Update king square - st->kingSquare[us] = kto; - // Update piece lists pieceList[us][KING][index[kfrom]] = kto; pieceList[us][ROOK][index[rfrom]] = rto; @@ -1106,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); @@ -1187,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; @@ -1235,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 @@ -1251,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; @@ -1272,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); @@ -1289,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 { @@ -1311,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] = { @@ -1325,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)); @@ -1337,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(); + + // 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]; - // Find all attackers to the destination square, with the moving piece - // removed, but possibly an X-ray attacker added behind it. - occ = occupied_squares(); + 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) @@ -1357,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)) @@ -1410,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); @@ -1478,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; @@ -1519,9 +1560,6 @@ void Position::put_piece(Piece p, Square s) { set_bit(&byTypeBB[0], s); // HACK: byTypeBB[0] contains all occupied squares. pieceCount[c][pt]++; - - if (pt == KING) - st->kingSquare[c] = s; } @@ -1680,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;