From 0734b1fa82b9d50181e3d0a1c327d6c2673c6506 Mon Sep 17 00:00:00 2001 From: Calcitem Date: Sun, 10 Jan 2021 21:08:01 +0800 Subject: [PATCH] repetition: refactor: Add has_repeated() and has_game_cycle() --- src/position.cpp | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ src/position.h | 4 ++++ src/search.cpp | 38 +++++--------------------------------- 3 files changed, 57 insertions(+), 33 deletions(-) diff --git a/src/position.cpp b/src/position.cpp index b3b8428d..97215c56 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -475,6 +475,54 @@ out: } +#ifdef THREEFOLD_REPETITION +// Position::has_repeated() tests whether there has been at least one repetition +// of positions since the last remove. + +bool Position::has_repeated(Sanmill::Stack &ss) const +{ + for (int i = (int)posKeyHistory.size() - 2; i >= 0; i--) { + if (key() == posKeyHistory[i]) { + return true; + } + } + + int size = ss.size(); + + for (int i = size - 1; i >= 0; i--) { + if (type_of(ss[i].move) == MOVETYPE_REMOVE) { + break; + } + if (key() == ss[i].st.key) { + return true; + } + } + + return false; +} + + +/// Position::has_game_cycle() tests if the position has a move which draws by repetition. + +int repetition; + +bool Position::has_game_cycle() const +{ + for (auto i : posKeyHistory) { + if (key() == i) { + repetition++; + if (repetition == 3) { + repetition = 0; + return true; + } + } + } + + return false; +} +#endif // THREEFOLD_REPETITION + + /// Mill Game #ifdef THREEFOLD_REPETITION diff --git a/src/position.h b/src/position.h index f143c945..8e40385c 100644 --- a/src/position.h +++ b/src/position.h @@ -90,6 +90,10 @@ public: Color side_to_move() const; int game_ply() const; Thread *this_thread() const; +#ifdef THREEFOLD_REPETITION + bool has_game_cycle() const; + bool has_repeated(Sanmill::Stack &ss) const; +#endif // THREEFOLD_REPETITION int rule50_count() const; diff --git a/src/search.cpp b/src/search.cpp index e1229ae8..136e0358 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -66,9 +66,6 @@ void Search::clear() Threads.clear(); } -#ifdef THREEFOLD_REPETITION -int repetition; -#endif // THREEFOLD_REPETITION /// Thread::search() is the main iterative deepening loop. It calls search() /// repeatedly with increasing depth until the allocated thinking time has been @@ -97,21 +94,12 @@ int Thread::search() #ifdef THREEFOLD_REPETITION if (rootPos->get_phase() == Phase::moving) { - const Key key = rootPos->key(); - - for (auto i : posKeyHistory) { - if (key == i) - { - repetition++; - if (repetition == 3) { - repetition = 0; - return 3; - } - } + if (rootPos->has_game_cycle()) { + return 3; } #if defined(UCI_DO_BEST_MOVE) || defined(QT_GUI_LIB) - posKeyHistory.push_back(key); + posKeyHistory.push_back(rootPos->key()); #endif // UCI_DO_BEST_MOVE assert(posKeyHistory.size() < 256); @@ -319,24 +307,8 @@ Value search(Position *pos, Sanmill::Stack &ss, Depth depth, Depth ori // to pick a move and can't simply return VALUE_DRAW) then check to // see if the position is a repeat. if so, we can assume that // this line is a draw and return VALUE_DRAW. - - if (depth != originDepth) { - for (int i = (int)posKeyHistory.size() - 2; i >= 0; i--) { - if (posKey == posKeyHistory[i]) { - return VALUE_DRAW; - } - } - - int size = ss.size(); - - for (int i = size - 1; i >= 0; i--) { - if (type_of(ss[i].move) == MOVETYPE_REMOVE) { - break; - } - if (posKey == ss[i].st.key) { - return VALUE_DRAW; - } - } + if (depth != originDepth && pos->has_repeated(ss)) { + return VALUE_DRAW; } #endif // THREEFOLD_REPETITION