From 3d8140a54101a50860ba2e3eb0f2d6cce68bfe47 Mon Sep 17 00:00:00 2001 From: Marco Costalba Date: Mon, 18 Jul 2011 10:20:37 +0200 Subject: [PATCH] Retire history[] Use key saved in state instead. No functional change (in real games) and no speed regression. Signed-off-by: Marco Costalba --- src/position.cpp | 57 ++++++++++++++++++------------------------------ src/position.h | 9 +------- src/uci.cpp | 12 +++++++++- 3 files changed, 33 insertions(+), 45 deletions(-) diff --git a/src/position.cpp b/src/position.cpp index abe24a52..28fa3695 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -99,7 +99,6 @@ CheckInfo::CheckInfo(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; nodes = 0; @@ -113,18 +112,6 @@ Position::Position(const string& fen, bool isChess960, int th) { } -/// Position::detach() copies the content of the current state and castling -/// masks inside the position itself. This is needed when the st pointee could -/// become stale, as example because the caller is about to going out of scope. - -void Position::detach() { - - startState = *st; - st = &startState; - st->previous = NULL; // As a safe guard -} - - /// Position::from_fen() initializes the position object with the given FEN /// string. This function is not very robust - make sure that input FENs are /// correct (this is assumed to be the responsibility of the GUI). @@ -775,27 +762,16 @@ bool Position::move_gives_check(Move m, const CheckInfo& ci) const { /// Position::do_setup_move() makes a permanent move on the board. It should /// be used when setting up a position on board. You can't undo the move. -void Position::do_setup_move(Move m) { +void Position::do_setup_move(Move m, StateInfo& newSt) { assert(move_is_ok(m)); - StateInfo newSt; - // Update the number of full moves after black's move if (sideToMove == BLACK) fullMoves++; do_move(m, newSt); - // Reset "game ply" in case we made a non-reversible move. - // "game ply" is used for repetition detection. - if (st->rule50 == 0) - st->gamePly = 0; - - // Our StateInfo newSt is about going out of scope so copy - // its content before it disappears. - detach(); - assert(is_ok()); } @@ -834,16 +810,13 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI newSt.previous = st; st = &newSt; - // Save the current key to the history[] array, in order to be able to - // detect repetition draws. - history[st->gamePly++] = key; - // Update side to move key ^= zobSideToMove; // 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->gamePly++; st->pliesFromNull++; if (move_is_castle(m)) @@ -1369,10 +1342,6 @@ void Position::do_null_move(StateInfo& backupSt) { backupSt.pliesFromNull = st->pliesFromNull; st->previous = &backupSt; - // Save the current key to the history[] array, in order to be able to - // detect repetition draws. - history[st->gamePly++] = st->key; - // Update the necessary information if (st->epSquare != SQ_NONE) st->key ^= zobEp[st->epSquare]; @@ -1383,6 +1352,7 @@ void Position::do_null_move(StateInfo& backupSt) { sideToMove = opposite_color(sideToMove); st->epSquare = SQ_NONE; st->rule50++; + st->gamePly++; st->pliesFromNull = 0; st->value += (sideToMove == WHITE) ? TempoValue : -TempoValue; @@ -1699,9 +1669,24 @@ bool Position::is_draw() const { // Draw by repetition? if (!SkipRepetition) - 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; + { + int i = 4, e = Min(Min(st->gamePly, st->rule50), st->pliesFromNull); + + if (i <= e) + { + StateInfo* stp = st->previous->previous; + + do { + stp = stp->previous->previous; + + if (stp->key == st->key) + return true; + + i +=2; + + } while (i <= e); + } + } return false; } diff --git a/src/position.h b/src/position.h index c1f63928..431d059c 100644 --- a/src/position.h +++ b/src/position.h @@ -26,11 +26,6 @@ #include "move.h" #include "types.h" -/// Maximum number of plies per game (220 should be enough, because the -/// maximum search depth is 100, and during position setup we reset the -/// move counter for every non-reversible move). -const int MaxGameLength = 220; - /// The checkInfo struct is initialized at c'tor time and keeps info used /// to detect if a move gives check. @@ -168,7 +163,7 @@ public: bool pawn_is_passed(Color c, Square s) const; // Doing and undoing moves - void do_setup_move(Move m); + void do_setup_move(Move m, StateInfo& st); void do_move(Move m, StateInfo& st); void do_move(Move m, StateInfo& st, const CheckInfo& ci, bool moveIsCheck); void undo_move(Move m); @@ -219,7 +214,6 @@ private: // Initialization helper functions (used while setting up a position) void clear(); - void detach(); void put_piece(Piece p, Square s); void set_castle(int f, Square ksq, Square rsq); void set_castling_rights(char token); @@ -258,7 +252,6 @@ private: int index[64]; // [square] // Other info - Key history[MaxGameLength]; int castleRightsMask[64]; // [square] Square castleRookSquare[16]; // [castleRight] StateInfo startState; diff --git a/src/uci.cpp b/src/uci.cpp index e6f01d3c..fb24bb26 100644 --- a/src/uci.cpp +++ b/src/uci.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include "evaluate.h" #include "misc.h" @@ -36,6 +37,10 @@ namespace { // FEN string for the initial position const string StartPositionFEN = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"; + // Keep track of position keys along the setup moves (from start position to the + // position just before to start searching). This is needed by draw detection. + std::vector SetupState; + // UCIParser is a class for parsing UCI input. The class // is actually a string stream built on a given input string. typedef istringstream UCIParser; @@ -140,8 +145,13 @@ namespace { else return; // Parse move list (if any) + SetupState.clear(); + while (up >> token && (m = move_from_uci(pos, token)) != MOVE_NONE) - pos.do_setup_move(m); + { + SetupState.push_back(StateInfo()); + pos.do_setup_move(m, SetupState.back()); + } } -- 2.39.2