X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fposition.cpp;h=5026ed761f02a96ba9b564b0ee15d814e879cef2;hp=cd2a596572b48e7958e4dc9dcd855d87be27bb6a;hb=5c3ebd1fbfc8cb623dd49aabd03c33a7fcbaf127;hpb=3ccdb57d6f8a90fbd31cc4cfcd8be59f04c21d64 diff --git a/src/position.cpp b/src/position.cpp index cd2a5965..5026ed76 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -74,23 +74,23 @@ CheckInfo::CheckInfo(const Position& pos) { } -/// Position c'tors. Here we always create a slower but safer copy of -/// the original position or the FEN string, we want the new born Position -/// object do not depend on any external data. Instead if we know what we -/// are doing and we need speed we can create a position with default -/// c'tor Position() and then use just fast_copy(). +/// Position c'tors. Here we always create a copy of the original position +/// or the FEN string, we want the new born Position object do not depend +/// on any external data so we detach state pointer from the source one. -Position::Position() {} +Position::Position(int th) : threadID(th) {} -Position::Position(const Position& pos) { +Position::Position(const Position& pos, int th) { memcpy(this, &pos, sizeof(Position)); detach(); // Always detach() in copy c'tor to avoid surprises + threadID = th; } -Position::Position(const string& fen) { +Position::Position(const string& fen, int th) { from_fen(fen); + threadID = th; } @@ -340,7 +340,7 @@ void Position::print(Move m) const { std::cout << std::endl; if (m != MOVE_NONE) { - Position p(*this); + Position p(*this, thread()); string col = (color_of_piece_on(move_from(m)) == BLACK ? ".." : ""); std::cout << "Move is: " << col << move_to_san(p, m) << std::endl; } @@ -703,7 +703,7 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI // pointer to point to the new, ready to be updated, state. struct ReducedStateInfo { Key pawnKey, materialKey; - int castleRights, rule50, pliesFromNull; + int castleRights, rule50, gamePly, pliesFromNull; Square epSquare; Score value; Value npMaterial[2]; @@ -715,8 +715,7 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI // Save the current key to the history[] array, in order to be able to // detect repetition draws. - history[gamePly] = key; - gamePly++; + history[st->gamePly++] = key; // Update side to move key ^= zobSideToMove; @@ -773,7 +772,7 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI } // Prefetch TT access as soon as we know key is updated - TT.prefetch(key); + prefetch((char*)TT.first_entry(key)); // Move the piece Bitboard move_bb = make_move_bb(from, to); @@ -808,6 +807,46 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI key ^= zobEp[st->epSquare]; } } + + if (pm) // promotion ? + { + PieceType promotion = move_promotion_piece(m); + + assert(promotion >= KNIGHT && promotion <= QUEEN); + + // Insert promoted piece instead of pawn + clear_bit(&(byTypeBB[PAWN]), to); + set_bit(&(byTypeBB[promotion]), to); + board[to] = piece_of_color_and_type(us, promotion); + + // Update piece counts + pieceCount[us][promotion]++; + pieceCount[us][PAWN]--; + + // Update material key + st->materialKey ^= zobrist[us][PAWN][pieceCount[us][PAWN]]; + st->materialKey ^= zobrist[us][promotion][pieceCount[us][promotion]-1]; + + // Update piece lists, move the last pawn at index[to] position + // and shrink the list. Add a new promotion piece to the list. + 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; + + // Partially revert hash keys update + key ^= zobrist[us][PAWN][to] ^ zobrist[us][promotion][to]; + st->pawnKey ^= zobrist[us][PAWN][to]; + + // Partially revert and update incremental scores + st->value -= pst(us, PAWN, to); + st->value += pst(us, promotion, to); + + // Update material + st->npMaterial[us] += piece_value_midgame(promotion); + } } // Update incremental scores @@ -816,46 +855,6 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI // Set capture piece st->capture = capture; - if (pm) // promotion ? - { - PieceType promotion = move_promotion_piece(m); - - assert(promotion >= KNIGHT && promotion <= QUEEN); - - // Insert promoted piece instead of pawn - clear_bit(&(byTypeBB[PAWN]), to); - set_bit(&(byTypeBB[promotion]), to); - board[to] = piece_of_color_and_type(us, promotion); - - // Update piece counts - pieceCount[us][promotion]++; - pieceCount[us][PAWN]--; - - // Update material key - st->materialKey ^= zobrist[us][PAWN][pieceCount[us][PAWN]]; - st->materialKey ^= zobrist[us][promotion][pieceCount[us][promotion]-1]; - - // Update piece lists, move the last pawn at index[to] position - // and shrink the list. Add a new promotion piece to the list. - 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; - - // Partially revert hash keys update - key ^= zobrist[us][PAWN][to] ^ zobrist[us][promotion][to]; - st->pawnKey ^= zobrist[us][PAWN][to]; - - // Partially revert and update incremental scores - st->value -= pst(us, PAWN, to); - st->value += pst(us, promotion, to); - - // Update material - st->npMaterial[us] += piece_value_midgame(promotion); - } - // Update the key with the final value st->key = key; @@ -901,17 +900,25 @@ void Position::do_capture_move(Key& key, PieceType capture, Color them, Square t Square capsq = to; - if (ep) // en passant ? + // If the captured piece was a pawn, update pawn hash key, + // otherwise update non-pawn material. + if (capture == PAWN) { - capsq = (them == BLACK)? (to - DELTA_N) : (to - DELTA_S); + if (ep) // en passant ? + { + capsq = (them == BLACK)? (to - DELTA_N) : (to - DELTA_S); - assert(to == st->epSquare); - assert(relative_rank(opposite_color(them), to) == RANK_6); - assert(piece_on(to) == EMPTY); - assert(piece_on(capsq) == piece_of_color_and_type(them, PAWN)); + assert(to == st->epSquare); + assert(relative_rank(opposite_color(them), to) == RANK_6); + assert(piece_on(to) == EMPTY); + assert(piece_on(capsq) == piece_of_color_and_type(them, PAWN)); - board[capsq] = EMPTY; + board[capsq] = EMPTY; + } + st->pawnKey ^= zobrist[them][PAWN][capsq]; } + else + st->npMaterial[them] -= piece_value_midgame(capture); // Remove captured piece clear_bit(&(byColorBB[them]), capsq); @@ -924,13 +931,6 @@ void Position::do_capture_move(Key& key, PieceType capture, Color them, Square t // Update incremental scores st->value -= pst(them, capture, capsq); - // If the captured piece was a pawn, update pawn hash key, - // otherwise update non-pawn material. - if (capture == PAWN) - st->pawnKey ^= zobrist[them][PAWN][capsq]; - else - st->npMaterial[them] -= piece_value_midgame(capture); - // Update piece count pieceCount[them][capture]--; @@ -1060,7 +1060,6 @@ void Position::undo_move(Move m) { assert(is_ok()); assert(move_is_ok(m)); - gamePly--; sideToMove = opposite_color(sideToMove); if (move_is_castle(m)) @@ -1110,7 +1109,6 @@ void Position::undo_move(Move m) { 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); @@ -1245,21 +1243,20 @@ void Position::do_null_move(StateInfo& backupSt) { // Save the current key to the history[] array, in order to be able to // detect repetition draws. - history[gamePly] = st->key; + history[st->gamePly++] = st->key; // Update the necessary information if (st->epSquare != SQ_NONE) st->key ^= zobEp[st->epSquare]; st->key ^= zobSideToMove; - TT.prefetch(st->key); + prefetch((char*)TT.first_entry(st->key)); sideToMove = opposite_color(sideToMove); st->epSquare = SQ_NONE; st->rule50++; st->pliesFromNull = 0; st->value += (sideToMove == WHITE) ? TempoValue : -TempoValue; - gamePly++; } @@ -1281,7 +1278,7 @@ void Position::undo_null_move() { // Update the necessary information sideToMove = opposite_color(sideToMove); st->rule50--; - gamePly--; + st->gamePly--; } @@ -1310,11 +1307,11 @@ int Position::see_sign(Move m) const { Square from = move_from(m); Square to = move_to(m); - // Early return if SEE cannot be negative because capturing piece value - // is not bigger then captured one. - if ( midgame_value_of_piece_on(from) <= midgame_value_of_piece_on(to) - && type_of_piece_on(from) != KING) - return 1; + // Early return if SEE cannot be negative because captured piece value + // is not less then capturing one. Note that king moves always return + // here because king midgame value is set to 0. + if (midgame_value_of_piece_on(to) >= midgame_value_of_piece_on(from)) + return 1; return see(from, to); } @@ -1478,7 +1475,6 @@ void Position::clear() { pieceList[0][i][j] = pieceList[1][i][j] = SQ_NONE; sideToMove = WHITE; - gamePly = 0; initialKFile = FILE_E; initialKRFile = FILE_H; initialQRFile = FILE_A; @@ -1493,7 +1489,7 @@ void Position::clear() { void Position::reset_game_ply() { - gamePly = 0; + st->gamePly = 0; } @@ -1671,8 +1667,8 @@ bool Position::is_draw() const { return true; // Draw by repetition? - for (int i = 4; i <= Min(Min(gamePly, st->rule50), st->pliesFromNull); i += 2) - if (history[gamePly - i] == st->key) + for (int i = 4, e = Min(Min(st->gamePly, st->rule50), st->pliesFromNull); i <= e; i += 2) + if (history[st->gamePly - i] == st->key) return true; return false; @@ -1787,6 +1783,7 @@ void Position::flipped_copy(const Position& pos) { assert(pos.is_ok()); clear(); + threadID = pos.thread(); // Board for (Square s = SQ_A1; s <= SQ_H8; s++)