X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fposition.cpp;h=2cdcb4aecca934f237adec65f63dc628d85f2908;hb=2218a5836a48a764e9b57f5996520b48e0b3d236;hp=8dab668bd90e1fb392338e7d933e6e6aa5647d96;hpb=9d1151575ddf3219c1ee157fe7a8336764e825ec;p=stockfish diff --git a/src/position.cpp b/src/position.cpp index 8dab668b..2cdcb4ae 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -358,16 +358,16 @@ const string Position::fen() const { ss << (sideToMove == WHITE ? " w " : " b "); if (can_castle(WHITE_OO)) - ss << (chess960 ? char(toupper(file_to_char(file_of(castle_rook_square(WHITE, KING_SIDE))))) : 'K'); + ss << (chess960 ? file_to_char(file_of(castle_rook_square(WHITE, KING_SIDE)), false) : 'K'); if (can_castle(WHITE_OOO)) - ss << (chess960 ? char(toupper(file_to_char(file_of(castle_rook_square(WHITE, QUEEN_SIDE))))) : 'Q'); + ss << (chess960 ? file_to_char(file_of(castle_rook_square(WHITE, QUEEN_SIDE)), false) : 'Q'); if (can_castle(BLACK_OO)) - ss << (chess960 ? file_to_char(file_of(castle_rook_square(BLACK, KING_SIDE))) : 'k'); + ss << (chess960 ? file_to_char(file_of(castle_rook_square(BLACK, KING_SIDE)), true) : 'k'); if (can_castle(BLACK_OOO)) - ss << (chess960 ? file_to_char(file_of(castle_rook_square(BLACK, QUEEN_SIDE))) : 'q'); + ss << (chess960 ? file_to_char(file_of(castle_rook_square(BLACK, QUEEN_SIDE)), true) : 'q'); if (st->castleRights == CASTLES_NONE) ss << '-'; @@ -802,9 +802,10 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI pieceList[them][capture][index[lastSquare]] = lastSquare; pieceList[them][capture][pieceCount[them][capture]] = SQ_NONE; - // Update hash keys + // Update material hash key and prefetch access to materialTable k ^= Zobrist::psq[them][capture][capsq]; st->materialKey ^= Zobrist::psq[them][capture][pieceCount[them][capture]]; + prefetch((char*)thisThread->materialTable[st->materialKey]); // Update incremental scores st->psqScore -= pieceSquareTable[make_piece(them, capture)][capsq]; @@ -831,7 +832,7 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI st->castleRights &= ~cr; } - // Prefetch TT access as soon as we know key is updated + // Prefetch TT access as soon as we know the new hash key prefetch((char*)TT.first_entry(k)); // Move the piece @@ -894,17 +895,14 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI st->npMaterial[us] += PieceValue[MG][promotion]; } - // Update pawn hash key + // Update pawn hash key and prefetch access to pawnsTable st->pawnKey ^= Zobrist::psq[us][PAWN][from] ^ Zobrist::psq[us][PAWN][to]; + prefetch((char*)thisThread->pawnsTable[st->pawnKey]); // Reset rule 50 draw counter st->rule50 = 0; } - // Prefetch pawn and material hash tables - prefetch((char*)thisThread->pawnsTable[st->pawnKey]); - prefetch((char*)thisThread->materialTable[st->materialKey]); - // Update incremental scores st->psqScore += psq_delta(piece, from, to); @@ -955,10 +953,7 @@ void Position::undo_move(Move m) { sideToMove = ~sideToMove; if (type_of(m) == CASTLE) - { - do_castle_move(m); - return; - } + return do_castle_move(m); Color us = sideToMove; Color them = ~us; @@ -1054,30 +1049,24 @@ void Position::do_castle_move(Move m) { assert(is_ok(m)); assert(type_of(m) == CASTLE); - Square kto, kfrom, rfrom, rto, kAfter, rAfter; - Color us = sideToMove; - Square kBefore = from_sq(m); - Square rBefore = to_sq(m); + Square kfrom, kto, rfrom, rto; - // Find after-castle squares for king and rook - if (rBefore > kBefore) // O-O + bool kingSide = to_sq(m) > from_sq(m); + kfrom = kto = from_sq(m); + rfrom = rto = to_sq(m); + + if (Do) { - kAfter = relative_square(us, SQ_G1); - rAfter = relative_square(us, SQ_F1); + kto = relative_square(us, kingSide ? SQ_G1 : SQ_C1); + rto = relative_square(us, kingSide ? SQ_F1 : SQ_D1); } - else // O-O-O + else { - kAfter = relative_square(us, SQ_C1); - rAfter = relative_square(us, SQ_D1); + kfrom = relative_square(us, kingSide ? SQ_G1 : SQ_C1); + rfrom = relative_square(us, kingSide ? SQ_F1 : SQ_D1); } - kfrom = Do ? kBefore : kAfter; - rfrom = Do ? rBefore : rAfter; - - kto = Do ? kAfter : kBefore; - rto = Do ? rAfter : rBefore; - assert(piece_on(kfrom) == make_piece(us, KING)); assert(piece_on(rfrom) == make_piece(us, ROOK)); @@ -1090,11 +1079,9 @@ void Position::do_castle_move(Move m) { byColorBB[us] ^= k_from_to_bb ^ r_from_to_bb; // Update board - Piece king = make_piece(us, KING); - Piece rook = make_piece(us, ROOK); board[kfrom] = board[rfrom] = NO_PIECE; - board[kto] = king; - board[rto] = rook; + board[kto] = make_piece(us, KING); + board[rto] = make_piece(us, ROOK); // Update piece lists pieceList[us][KING][index[kfrom]] = kto; @@ -1109,8 +1096,8 @@ void Position::do_castle_move(Move m) { st->capturedType = NO_PIECE_TYPE; // Update incremental scores - st->psqScore += psq_delta(king, kfrom, kto); - st->psqScore += psq_delta(rook, rfrom, rto); + st->psqScore += psq_delta(make_piece(us, KING), kfrom, kto); + st->psqScore += psq_delta(make_piece(us, ROOK), rfrom, rto); // Update hash key st->key ^= Zobrist::psq[us][KING][kfrom] ^ Zobrist::psq[us][KING][kto]; @@ -1140,47 +1127,42 @@ void Position::do_castle_move(Move m) { } -/// Position::do_null_move() is used to do/undo a "null move": It flips the side -/// to move and updates the hash key without executing any move on the board. -template -void Position::do_null_move(StateInfo& backupSt) { +/// Position::do(undo)_null_move() is used to do(undo) a "null move": It flips +/// the side to move without executing any move on the board. - assert(!checkers()); +void Position::do_null_move(StateInfo& newSt) { - // Back up the information necessary to undo the null move to the supplied - // StateInfo object. Note that differently from normal case here backupSt - // is actually used as a backup storage not as the new state. This reduces - // the number of fields to be copied. - StateInfo* src = Do ? st : &backupSt; - StateInfo* dst = Do ? &backupSt : st; + assert(!checkers()); - dst->key = src->key; - dst->epSquare = src->epSquare; - dst->psqScore = src->psqScore; - dst->rule50 = src->rule50; - dst->pliesFromNull = src->pliesFromNull; + memcpy(&newSt, st, sizeof(StateInfo)); // Fully copy here - sideToMove = ~sideToMove; + newSt.previous = st; + st = &newSt; - if (Do) + if (st->epSquare != SQ_NONE) { - if (st->epSquare != SQ_NONE) - st->key ^= Zobrist::enpassant[file_of(st->epSquare)]; - - st->key ^= Zobrist::side; - prefetch((char*)TT.first_entry(st->key)); - + st->key ^= Zobrist::enpassant[file_of(st->epSquare)]; st->epSquare = SQ_NONE; - st->rule50++; - st->pliesFromNull = 0; } + st->key ^= Zobrist::side; + prefetch((char*)TT.first_entry(st->key)); + + st->rule50++; + st->pliesFromNull = 0; + + sideToMove = ~sideToMove; + assert(pos_is_ok()); } -// Explicit template instantiations -template void Position::do_null_move(StateInfo& backupSt); -template void Position::do_null_move(StateInfo& backupSt); +void Position::undo_null_move() { + + assert(!checkers()); + + st = st->previous; + sideToMove = ~sideToMove; +} /// Position::see() is a static exchange evaluator: It tries to estimate the