From 8a19b29a65ad8a6d366b27760f97ef5a56dd7c7a Mon Sep 17 00:00:00 2001 From: QueensGambit Date: Fri, 28 Jan 2022 20:05:23 +0100 Subject: [PATCH] Avoid repeating positions in Xiangqi (closes #101) Set stalemate as lost game --- .../environments/fairy_state/fairyboard.cpp | 19 ++++++++++++++----- .../environments/fairy_state/fairystate.cpp | 12 ++++++++---- engine/src/uci/crazyara.cpp | 1 + 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/engine/src/environments/fairy_state/fairyboard.cpp b/engine/src/environments/fairy_state/fairyboard.cpp index 7f16c2d0..496d0e23 100644 --- a/engine/src/environments/fairy_state/fairyboard.cpp +++ b/engine/src/environments/fairy_state/fairyboard.cpp @@ -41,6 +41,11 @@ Key FairyBoard::hash_key() const { } bool FairyBoard::is_terminal() const { + // "Unlike in chess, in which stalemate is a draw, in xiangqi, it is a loss for the stalemated player." + // -- https://en.wikipedia.org/wiki/Xiangqi + if (this->number_repetitions() != 0) { + return true; + } for (const ExtMove move : MoveList(*this)) { return false; } @@ -49,13 +54,17 @@ bool FairyBoard::is_terminal() const { size_t FairyBoard::number_repetitions() const { StateInfo *st = state(); - if (st->repetition == 0) { - return 0; - } - else if (st->repetition) { + // st->repetition: + // "It is the ply distance from the previous + // occurrence of the same position, negative in the 3-fold case, or zero" -- fairy/position.cpp + // if the position was not repeated. + if (st->repetition > 0) { return 1; } - else return 0; + if (st->repetition < 0) { + return 2; + } + return 0; } Result get_result(const FairyBoard &pos, bool inCheck) { diff --git a/engine/src/environments/fairy_state/fairystate.cpp b/engine/src/environments/fairy_state/fairystate.cpp index 5897fcfc..d3f4e423 100644 --- a/engine/src/environments/fairy_state/fairystate.cpp +++ b/engine/src/environments/fairy_state/fairystate.cpp @@ -84,10 +84,14 @@ Action FairyState::uci_to_action(string &uciStr) const { TerminalType FairyState::is_terminal(size_t numberLegalMoves, float &customTerminalValue) const { if (numberLegalMoves == 0) { - if (board.checkers()) { - return TERMINAL_LOSS; - } - return TERMINAL_DRAW; + // "Unlike in chess, in which stalemate is a draw, in xiangqi, it is a loss for the stalemated player." + // -- https://en.wikipedia.org/wiki/Xiangqi + return TERMINAL_LOSS; + } + if (this->number_repetitions() != 0) { + // "If one side perpetually checks and the other side perpetually chases, the checking side has to stop or be ruled to have lost." + // -- https://en.wikipedia.org/wiki/Xiangqi + return TERMINAL_WIN; } return TERMINAL_NONE; } diff --git a/engine/src/uci/crazyara.cpp b/engine/src/uci/crazyara.cpp index f986f145..d358f1d5 100644 --- a/engine/src/uci/crazyara.cpp +++ b/engine/src/uci/crazyara.cpp @@ -513,6 +513,7 @@ void CrazyAra::init() // This is a workaround for compatibility with Fairy-Stockfish // Option with key "Threads" is also removed. (See /3rdparty/Fairy-Stockfish/src/ucioption.cpp) Options.erase("Hash"); + Options.erase("Use NNUE"); #endif }