Adjudicate optional game ends in CECP protocol
authorFabian Fichter <ianfab@users.noreply.github.com>
Sun, 14 Jun 2020 12:52:25 +0000 (14:52 +0200)
committerFabian Fichter <ianfab@users.noreply.github.com>
Fri, 19 Jun 2020 14:03:34 +0000 (16:03 +0200)
Closes #150.

src/position.h
src/search.cpp

index 12df6c1..a0ca7cb 100644 (file)
@@ -253,9 +253,10 @@ public:
   bool is_chess960() const;
   Thread* this_thread() const;
   bool is_immediate_game_end() const;
-  bool is_game_end(Value& result, int ply = 0) const;
-  bool is_optional_game_end(Value& result, int ply = 0, int countStarted = 0) const;
   bool is_immediate_game_end(Value& result, int ply = 0) const;
+  bool is_optional_game_end() const;
+  bool is_optional_game_end(Value& result, int ply = 0, int countStarted = 0) const;
+  bool is_game_end(Value& result, int ply = 0) const;
   Value material_counting_result() const;
   bool has_game_cycle(int ply) const;
   bool has_repeated() const;
@@ -729,6 +730,11 @@ inline bool Position::is_immediate_game_end() const {
   return is_immediate_game_end(result);
 }
 
+inline bool Position::is_optional_game_end() const {
+  Value result;
+  return is_optional_game_end(result);
+}
+
 inline bool Position::is_game_end(Value& result, int ply) const {
   return is_immediate_game_end(result, ply) || is_optional_game_end(result, ply);
 }
index a2f4640..7629f9e 100644 (file)
@@ -229,7 +229,7 @@ void MainThread::search() {
   Time.init(rootPos, Limits, us, rootPos.game_ply());
   TT.new_search();
 
-  if (rootMoves.empty())
+  if (rootMoves.empty() || (Options["Protocol"] == "xboard" && rootPos.is_optional_game_end()))
   {
       rootMoves.emplace_back(MOVE_NONE);
       Value variantResult;
@@ -237,10 +237,14 @@ void MainThread::search() {
                     : rootPos.checkers()                 ? rootPos.checkmate_value()
                                                          : rootPos.stalemate_value();
       if (Options["Protocol"] == "xboard")
+      {
+          // rotate MOVE_NONE to front (for optional game end)
+          std::rotate(rootMoves.rbegin(), rootMoves.rbegin() + 1, rootMoves.rend());
           sync_cout << (  result == VALUE_DRAW ? "1/2-1/2 {Draw}"
                         : (rootPos.side_to_move() == BLACK ? -result : result) == VALUE_MATE ? "1-0 {White wins}"
                         : "0-1 {Black wins}")
                     << sync_endl;
+      }
       else
       sync_cout << "info depth 0 score "
                 << UCI::value(result)