repetition: refactor: Add has_repeated() and has_game_cycle()

This commit is contained in:
Calcitem 2021-01-10 21:08:01 +08:00
parent 31da244933
commit 0734b1fa82
3 changed files with 57 additions and 33 deletions

View File

@ -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<Position> &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

View File

@ -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<Position> &ss) const;
#endif // THREEFOLD_REPETITION
int rule50_count() const;

View File

@ -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<Position> &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