Winboard janggi "OpeningBook" compatibility development

Discussions about Winboard/Xboard. News about engines or programs to use with these GUIs (e.g. tournament managers or adapters) belong in this sub forum.

Moderator: Andres Valverde

Re: Winboard janggi "OpeningBook" compatibility development

Postby janggi-korea » 08 Nov 2020, 05:17

Okay. I've posted all the code we've been working on in case you don't know. The engine sometimes ignores Winboard commands and only ponders.

Code: Select all
/*
  Fairy-Stockfish, a UCI chess variant playing engine derived from Stockfish
  Copyright (C) 2018-2020 Fabian Fichter

  Fairy-Stockfish is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  Fairy-Stockfish is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <iostream>
#include <string>

#include "evaluate.h"
#include "misc.h"
#include "partner.h"
#include "search.h"
#include "thread.h"
#include "types.h"
#include "uci.h"
#include "xboard.h"

namespace {

  const Search::LimitsType analysisLimits = []{
    Search::LimitsType limits;
    limits.infinite = 1;
    return limits;
  }();

  // go() starts the search for game play, analysis, or perft.

  void go(Position& pos, Search::LimitsType limits, StateListPtr& states) {

    limits.startTime = now(); // As early as possible!

    Threads.start_thinking(pos, states, limits, false);
  }

  // setboard() is called when engine receives the "setboard" XBoard command.

  void setboard(Position& pos, std::deque<Move>& moveList, StateListPtr& states, std::string fen = "") {

    if (fen.empty())
        fen = variants.find(Options["UCI_Variant"])->second->startFen;

    states = StateListPtr(new std::deque<StateInfo>(1)); // Drop old and create a new one
    moveList.clear();
    pos.set(variants.find(Options["UCI_Variant"])->second, fen, Options["UCI_Chess960"], &states->back(), Threads.main());
  }

  // do_move() is called when engine needs to apply a move when using XBoard protocol.

  void do_move(Position& pos, std::deque<Move>& moveList, StateListPtr& states, Move m) {

    // transfer states back
    if (Threads.setupStates.get())
        states = std::move(Threads.setupStates);

    if (m == MOVE_NONE)
        return;
    moveList.push_back(m);
    states->emplace_back();
    pos.do_move(m, states->back());
  }

  // undo_move() is called when the engine receives the undo command in XBoard protocol.

  void undo_move(Position& pos, std::deque<Move>& moveList, StateListPtr& states) {

    // transfer states back
    if (Threads.setupStates.get())
        states = std::move(Threads.setupStates);

    pos.undo_move(moveList.back());
    states->pop_back();
    moveList.pop_back();
  }

} // namespace

namespace XBoard {

/// StateMachine::process_command() processes commands of the XBoard protocol.

void StateMachine::process_command(Position& pos, std::string token, std::istringstream& is, StateListPtr& states) {
  if(token == "rejected")
  {
      is >> token;
      if(token != "GOTMOVE") return; // [HGM] all other feature rejections are ignored
  }
  if (token == "GOTMOVE" && ponderMove == "") // [HGM] a search for thinking announces its termination
  {
      // abort search in bughouse when receiving "holding" command
      bool doMove = token != "holding" || Threads.abort.exchange(true);
//      Threads.stop = true;
//      Threads.main()->wait_for_search_finished();
      if (doMove)
      {
          Move m = Threads.main()->bestThread->rootMoves[0].pv[0];
          if(m != MOVE_NONE)
          {
              sync_cout << "move " << UCI::move(pos, m) << sync_endl; // print move
              do_move(pos, moveList, states, m);                     // and do it ourselves
              moveAfterSearch = false;
              if(Options["Ponder"] &&
                 (Threads.main()->bestThread->rootMoves[0].pv.size() > 1 ||
                  Threads.main()->bestThread->rootMoves[0].extract_ponder_from_tt(pos)))
              {
                  m = Threads.main()->bestThread->rootMoves[0].pv[1]; // ponder move
                  ponderMove = UCI::move(pos, m);                     // remember it (indicates we are pondering)
                  sync_cout << "Hint: " << ponderMove << sync_endl;   // print it
                  do_move(pos, moveList, states, m);                  // perform it
                  limits.startTime = now(); // As early as possible!
                  Threads.start_thinking(pos, states, limits, true);  // and start pondering
              }
          }
      }
  }
  else if(token == "GOTMOVE")
      ponderMove = "";
  else if (token == "protover")
  {
      std::string vars = "chess";
      for (std::string v : variants.get_keys())
          if (v != "chess")
              vars += "," + v;
      sync_cout << "feature setboard=1 usermove=1 time=1 memory=1 smp=1 colors=0 draw=0 "
                << "highlight=1 reuse=0 name=0 sigint=0 ping=1 debug=1 myname=\""
                << engine_info(false, true) << "\" " << "variants=\"" << vars << "\""
                << Options << sync_endl;
      sync_cout << "feature done=1" << sync_endl;
  }
  else if (token == "accepted" || token == "rejected") {}
  else if (token == "hover" || token == "put") {}
  else if (token == "lift")
  {
      if (is >> token)
      {
          Bitboard promotions = 0, captures = 0, quiets = 0;
          // Collect targets
        if(ponderMove != "") undo_move(pos, moveList, states);
          for (const auto& m : MoveList<LEGAL>(pos))
          {
              Square from = from_sq(m), to = to_sq(m);
              if (is_ok(from) && UCI::square(pos, from) == token && from != to)
              {
                  if (type_of(m) == PROMOTION)
                      promotions |= to;
                  else if (pos.capture(m))
                      captures |= to;
                  else
                  {
                      if (type_of(m) == CASTLING && !pos.is_chess960())
                          to = make_square(to > from ? pos.castling_kingside_file()
                                                     : pos.castling_queenside_file(), rank_of(from));
                      quiets |= to;
                  }
              }
          }
          // Generate color FEN
        if(ponderMove != "") do_move(pos, moveList, states, UCI::to_move(pos, ponderMove));
          int emptyCnt;
          std::ostringstream ss;
          for (Rank r = pos.max_rank(); r >= RANK_1; --r)
          {
              for (File f = FILE_A; f <= pos.max_file(); ++f)
              {
                  for (emptyCnt = 0; f <= pos.max_file() && !((promotions | captures | quiets) & make_square(f, r)); ++f)
                      ++emptyCnt;

                  if (emptyCnt)
                      ss << emptyCnt;

                  if (f <= pos.max_file())
                      ss << (promotions & make_square(f, r) ? "M" : captures & make_square(f, r) ? "R" : "Y");
              }

              if (r > RANK_1)
                  ss << '/';
          }
          sync_cout << "highlight " << ss.str() << sync_endl;
      }
  }
  else if (token == "ping")
  {
      if (!(is >> token))
          token = "";
      sync_cout << "pong " << token << sync_endl;
  }
  else if (token == "new")
  {
      Search::clear();
      setboard(pos, moveList, states);
      // play second by default
      playColor = ~pos.side_to_move();
      Threads.sit = false;
      Partner.reset();
  }
  else if (token == "variant")
  {
      if (is >> token)
          Options["UCI_Variant"] = token;
      setboard(pos, moveList, states);
  }
  else if (token == "force" || token == "result")
  {
      if(ponderMove != "") // we were pondering, stop that
      {
          Threads.stop = true;
          Threads.main()->wait_for_search_finished();
          undo_move(pos, moveList, states);
      }
      playColor = COLOR_NB;
  } 
  else if (token == "go")
  {
      playColor = pos.side_to_move();
      go(pos, limits, states);
      moveAfterSearch = true;
  }
  else if (token == "level" || token == "st" || token == "sd" || token == "time" || token == "otim")
  {
      int num;
      if (token == "level")
      {
          // moves to go
          is >> limits.movestogo;
          // base time
          is >> token;
          size_t idx = token.find(":");
          if (idx != std::string::npos)
              num = std::stoi(token.substr(0, idx)) * 60 + std::stoi(token.substr(idx + 1));
          else
              num = std::stoi(token) * 60;
          limits.time[WHITE] = num * 1000;
          limits.time[BLACK] = num * 1000;
          // increment
          is >> num;
          limits.inc[WHITE] = num * 1000;
          limits.inc[BLACK] = num * 1000;
      }
      else if (token == "sd")
          is >> limits.depth;
      else if (token == "st")
      {
          is >> num;
          limits.movetime = num * 1000;
          limits.time[WHITE] = limits.time[BLACK] = 0;
      }
      // Note: time/otim are in centi-, not milliseconds
      else if (token == "time")
      {
          is >> num;
          Color us = playColor != COLOR_NB ? playColor : pos.side_to_move();
          if (limits.time[us])
              limits.time[us] = num * 10;
      }
      else if (token == "otim")
      {
          is >> num;
          Color them = playColor != COLOR_NB ? ~playColor : ~pos.side_to_move();
          if (limits.time[them])
              limits.time[them] = num * 10;
      }
  }
  else if (token == "setboard")
  {
      std::string fen;
      std::getline(is >> std::ws, fen);
      // Check if setboard actually indicates a passing move
      // to avoid unnecessarily clearing the move history
      if (pos.pass())
      {
          StateInfo st;
          Position p;
          p.set(pos.variant(), fen, pos.is_chess960(), &st, pos.this_thread());
          Move m;
          std::string passMove = "@@@@";
          if ((m = UCI::to_move(pos, passMove)) != MOVE_NONE)
              do_move(pos, moveList, states, m);
          // apply setboard if passing does not lead to a match
          if (pos.key() != p.key())
              setboard(pos, moveList, states, fen);
      }
      else
          setboard(pos, moveList, states, fen);
      // Winboard sends setboard after passing moves
      if (pos.side_to_move() == playColor)
      {
          go(pos, limits, states);
          moveAfterSearch = true;
      }
  }
  else if (token == "cores")
  {
      if (is >> token)
          Options["Threads"] = token;
  }
  else if (token == "memory")
  {
      if (is >> token)
          Options["Hash"] = token;
  }
  else if (token == "hard" || token == "easy")
      Options["Ponder"] = token == "hard";
  else if (token == "option")
  {
      std::string name, value;
      is.get();
      std::getline(is, name, '=');
      std::getline(is, value);
      if (Options.count(name))
      {
          if (Options[name].get_type() == "check")
              value = value == "1" ? "true" : "false";
          Options[name] = value;
      }
  }
  else if (token == "analyze")
  {
      Options["UCI_AnalyseMode"] = std::string("true");
      go(pos, analysisLimits, states);
  }
  else if (token == "exit")
  {
      Threads.stop = true;
      Threads.main()->wait_for_search_finished();
      Options["UCI_AnalyseMode"] = std::string("false");
  }
  else if (token == "undo")
  {
      if (moveList.size())
      {
          if (Options["UCI_AnalyseMode"])
          {
              Threads.stop = true;
              Threads.main()->wait_for_search_finished();
          }
          undo_move(pos, moveList, states);
          if (Options["UCI_AnalyseMode"])
              go(pos, analysisLimits, states);
      }
  }
  else if (token == "remove")
  {
      if (moveList.size() > 1)
      {
          if (ponderMove != "")
          {
              Threads.stop = true;
              Threads.main()->wait_for_search_finished();
              undo_move(pos, moveList, states); // take back ponder move
          }
          undo_move(pos, moveList, states);
          undo_move(pos, moveList, states);
      }
  }

  else if (token == "?" && ponderMove == "" && !Options["UCI_AnalyseMode"])
  {
          Threads.stop = true;
          Threads.main()->wait_for_search_finished();
  }    
  // Bughouse commands
  else if (token == "partner")
      Partner.parse_partner(is);
  else if (token == "ptell")
  {
      Partner.parse_ptell(is, pos);
      // play move requested by partner
      if (moveAfterSearch && Partner.moveRequested)
      {
          Threads.stop = true;
          Threads.main()->wait_for_search_finished();
          sync_cout << "move " << UCI::move(pos, Partner.moveRequested) << sync_endl;
          do_move(pos, moveList, states, Partner.moveRequested);
          moveAfterSearch = false;
          Partner.moveRequested = MOVE_NONE;
      }
  }
  else if (token == "holding")
  {
      // holding [<white>] [<black>] <color><piece>
      std::string white_holdings, black_holdings;
      if (   std::getline(is, token, '[') && std::getline(is, white_holdings, ']')
          && std::getline(is, token, '[') && std::getline(is, black_holdings, ']'))
      {
          std::string fen;
          char color, pieceType;
          // Use the obtained holding if available to avoid race conditions
          if (is >> color && is >> pieceType)
          {
              fen = pos.fen();
              fen.insert(fen.find(']'), 1, toupper(color) == 'B' ? tolower(pieceType) : toupper(pieceType));
          }
          else
          {
              std::transform(black_holdings.begin(), black_holdings.end(), black_holdings.begin(), ::tolower);
              fen = pos.fen(false, false, 0, white_holdings + black_holdings);
          }
          setboard(pos, moveList, states, fen);
      }
      // restart search
      if (moveAfterSearch)
          go(pos, limits, states);
  }
  // Additional custom non-XBoard commands
  else if (token == "perft")
  {
      Search::LimitsType perft_limits;
      is >> perft_limits.perft;
      go(pos, perft_limits, states);
  }
  else if (token == "d")
      sync_cout << pos << sync_endl;
  else if (token == "eval")
      sync_cout << Eval::trace(pos) << sync_endl;
  // Move strings and unknown commands
 
  else if (token == "usermove")
  {
      // process move string
          is >> token;
      if(token == ponderMove) { // input move is a ponder hit
          Threads.main()->ponder = false; // Switch to normal search
          moveAfterSearch = true; // the move of which should be printed
          ponderMove = ""; // and remember we are no longer pondering
          return;
      }
      if (Options["UCI_AnalyseMode"] || ponderMove != "") // move received during search
      {
          Threads.stop = true;
          Threads.main()->wait_for_search_finished();
          if(ponderMove != "") // ponder miss, take ponder move back
              undo_move(pos, moveList, states);
          // do not clear ponderMove yet, to cause ignoring of the 'rejected' triggered by ponder stop
      }
      Move m;
      if ((m = UCI::to_move(pos, token)) != MOVE_NONE)
          do_move(pos, moveList, states, m);
      else
          sync_cout << "Illegal move: " << token << sync_endl;
      if (Options["UCI_AnalyseMode"])
          go(pos, analysisLimits, states);
      else if (pos.side_to_move() == playColor)
      {
          go(pos, limits, states);
          moveAfterSearch = true;
      }
  } else
          sync_cout << "Error (unknown command): " << token << sync_endl;}

} // namespace XBoard
janggi-korea
 
Posts: 130
Joined: 18 Aug 2020, 12:12

Re: Winboard janggi "OpeningBook" compatibility development

Postby H.G.Muller » 08 Nov 2020, 11:29

OK, thanks. At least I am back in sync now.

Indeed the code for 'force' I suggested earlier only takes care of stopping a ponder search. It should stop any search, and only in case of a ponder search it should retract the ponder move. So the code should be changed to:

Code: Select all
  else if (token == "force" || token == "result")
  {
      Threads.stop = true;
      Threads.main()->wait_for_search_finished();
      if(ponderMove != "") // we were pondering, stop that
      {
          undo_move(pos, moveList, states);
      }
      playColor = COLOR_NB;
  }

This assumes that it is not an error to call wait_for_search_finished() when there was no search going on, but that it just returns immediately in that case. (Which I do not know for sure, but which seems likely.)
User avatar
H.G.Muller
 
Posts: 3453
Joined: 16 Nov 2005, 12:02
Location: Diemen, NL

Re: Winboard janggi "OpeningBook" compatibility development

Postby janggi-korea » 08 Nov 2020, 12:49

Thanks for the quick fix. I did some tests.
When the engine contemplated, I ran the "edit game".
At this time, the engine does not immediately stop pondering.
and engine run "now move". And the ponder stops after I move once.
Test conclusion: When I run "edit game", the engine executes "now move". And then engine stop pondering after i moving 1 time.

[edit]
Last edited by janggi-korea on 14 Nov 2020, 07:00, edited 1 time in total.
janggi-korea
 
Posts: 130
Joined: 18 Aug 2020, 12:12

Re: Winboard janggi "OpeningBook" compatibility development

Postby H.G.Muller » 08 Nov 2020, 13:28

OK, I see. After the 'force' command aborted the thinking, the terminating search thread still sets the chain of events in motion that leads to printing of a move, and starting a new ponder search. CECP does not really define whether aborting thinking with 'force' should result in a move or not. But it should of course never lead to starting of pondering. I think it is best to suppress both printing the move and starting the ponder search after 'force' interrupted thinking, by replacing the line
Code: Select all
if (token == "GOTMOVE" && ponderMove == "") // [HGM] a search for thinking announces its termination

by
Code: Select all
if (token == "GOTMOVE" && ponderMove == "" && playColor != COLOR_NB) // [HGM] a search for thinking announces its termination
User avatar
H.G.Muller
 
Posts: 3453
Joined: 16 Nov 2005, 12:02
Location: Diemen, NL

Re: Winboard janggi "OpeningBook" compatibility development

Postby janggi-korea » 08 Nov 2020, 16:17

thanks.
nice, you are a genius. :D

PS.book
There are some bugs that I have checked.
During the book test, there was a bug where the engine did not start searching when there was no book connection after the first 3 moves.
I had this problem with the first few moves. If the book was long, there was no problem.
Check it out if you have time.
janggi-korea
 
Posts: 130
Joined: 18 Aug 2020, 12:12

Re: Winboard janggi "OpeningBook" compatibility development

Postby janggi-korea » 09 Nov 2020, 10:20

Sometimes the engine only searches and does not perform a move. At this time, the command of Winboard is ignored (eg edit game). I don't know what the hell is the problem. :?: :evil:
And sometimes Winboard is forced to shut down.
janggi-korea
 
Posts: 130
Joined: 18 Aug 2020, 12:12

Re: Winboard janggi "OpeningBook" compatibility development

Postby H.G.Muller » 09 Nov 2020, 10:33

Well, if you have a log for such a case, I am pretty sure it can be fixed.
User avatar
H.G.Muller
 
Posts: 3453
Joined: 16 Nov 2005, 12:02
Location: Diemen, NL

Re: Winboard janggi "OpeningBook" compatibility development

Postby janggi-korea » 10 Nov 2020, 15:01

thanks, I'm now building a new computer for testing. After assembly and testing, I will post the debug file.
janggi-korea
 
Posts: 130
Joined: 18 Aug 2020, 12:12

Re: Winboard janggi "OpeningBook" compatibility development

Postby janggi-korea » 11 Nov 2020, 16:39

In the meantime, my friend recorded the game. Perhaps an important bug was that when he was playing game engine or winboard refused to move. This is the most important bug. I posted the entire log file because I can't use the computer.

[edit]
Last edited by janggi-korea on 14 Nov 2020, 07:01, edited 1 time in total.
janggi-korea
 
Posts: 130
Joined: 18 Aug 2020, 12:12

Re: Winboard janggi "OpeningBook" compatibility development

Postby janggi-korea » 11 Nov 2020, 16:47

[edit]
Last edited by janggi-korea on 14 Nov 2020, 07:01, edited 1 time in total.
janggi-korea
 
Posts: 130
Joined: 18 Aug 2020, 12:12

Re: Winboard janggi "OpeningBook" compatibility development

Postby janggi-korea » 11 Nov 2020, 16:50

He told me he couldn't move the piece during the game, so I copied fen and restarted the winboard to move again and then connected the game again. (Winboard commands are ignored when the piece cannot be moved)
janggi-korea
 
Posts: 130
Joined: 18 Aug 2020, 12:12

Re: Winboard janggi "OpeningBook" compatibility development

Postby H.G.Muller » 11 Nov 2020, 16:51

Is there nothing after this? What I see seems all OK. It ends in SF starting a ponder search on the move e8e9 (as announced with the Hint command). This search runs until you pick up the Rook at a9 ('lift', to which it replies with a 'highlight' for indicating the 4 possible destinations in yellow), and then you put it down on a7 (a valid destination).

WinBoard should have continued sending time + otim commands, and "usermove a9a7", which then should have aborted the ponder search (because it was not the move being pondered on).

I see nothing of that in the log. But I am pretty sure that WinBoard should have sent it. So if the log really stops here then SF must have crashed on receiving the 'put' command. Which is an ignored command.

[Edit] Oh, I see you have posted the continuation of the log; these messages crossed.
User avatar
H.G.Muller
 
Posts: 3453
Joined: 16 Nov 2005, 12:02
Location: Diemen, NL

Re: Winboard janggi "OpeningBook" compatibility development

Postby H.G.Muller » 11 Nov 2020, 17:02

janggi-korea wrote:He told me he couldn't move the piece during the game, so I copied fen and restarted the winboard to move again and then connected the game again. (Winboard commands are ignored when the piece cannot be moved)

I am not sure at which point you copied a new FEN; I don't see that in the log. After which move was this supposed to have happened? What I see seems completely normal behavior of the engine. The second posting with the log seems the continuation of the first: it gives Thinking Output for the next depth (24) after the "usermove" command interrupts the ponder search (with a miss). Then there are a number of moves where you cut the thinking short with 'Move now', and it appears to obey those commands.

Finally SF sees it can checkmate in 1, it plays the move, announces the mate. And XBoard has detected the mate too ('XBoard adjudication'), and sends the 'result' command.
User avatar
H.G.Muller
 
Posts: 3453
Joined: 16 Nov 2005, 12:02
Location: Diemen, NL

Re: Winboard janggi "OpeningBook" compatibility development

Postby janggi-korea » 13 Nov 2020, 01:41

sorry,.
ok.. i'll test it correctly
janggi-korea
 
Posts: 130
Joined: 18 Aug 2020, 12:12

Re: Winboard janggi "OpeningBook" compatibility development

Postby janggi-korea » 14 Nov 2020, 07:04

[edit] Perhaps I used an older version of Winboard. This is because i have newly installed my computer.
Let me check a little more.
janggi-korea
 
Posts: 130
Joined: 18 Aug 2020, 12:12

Re: Winboard janggi "OpeningBook" compatibility development

Postby H.G.Muller » 14 Nov 2020, 11:54

OK, I think I understand what is going on. The engine is pondering, and you play a move that causes a 'book hit'. This means that WinBoard cannot just send the move to the engine, because the engine would then start thinking and play its own move. While you want it to play the book move. So it switches the engine to 'force' mode first, and then sends the move (b3a3), so that the engine will not reply to it. And then it sends the book move (c9a6).

The problem is that all this is sent before the engine's I/O thread has received confirmation that the ponder search has been aborted (by the 'force'). So it thinks the engine is still pondering when it receives the usermove, and will again try to abort pondering, taking back the last move (which it assumed to be the ponder move). So it takes back too many moves, with as a result that the game state in the engine no longer is the same as the game state in the GUI, and all moves the GUI allows will be considered illegal by the engine. (Presumably because they do not agree on which player should move.)

I guess we should make the code we put in SF to terminate a ponder search a bit more robust, so that it doesn't get upset when it receives two termination requests immediately after each other. Currently ponder termination (by force/result or by a usermove) immediately retracts the ponder move, but leaves resetting of the ponderMove variable for the next incoming "rejected GOTMOVE", to make the processing of that command aware that the move it has from the latest search was the move from a ponder search, and should not be sent to the GUI. But that makes additional commands that should abort pondering and come in before the 'rejected' erroneously think the ponder search is still running, so they try to terminate it again (which is harmless) and take back the ponder move again (which is fatal).

I guess the solution is to not just leave the ponderMove variable unchanged after taking back the ponder move, but change it to some other non-empty string (say "stop"). The processing of the "rejected GOTMOVE" then still can see the latest search was a ponder search (because ponderMove is non-empty), but the taking back of the ponder move on commands that abort pondering can then test whether the engine is really still pondering (ponderMove != "" && ponderMove != "stop"), or whether the ponder move has already been taken back, or no pondering has been going on at all.

So change the processing of force/result to:
Code: Select all
  else if (token == "force" || token == "result")
  {
      Threads.stop = true;
      Threads.main()->wait_for_search_finished();
      if(ponderMove != "" && ponderMove != "stop") // we were pondering, stop that
      {
          undo_move(pos, moveList, states);
          ponderMove = "stop";
      }
      playColor = COLOR_NB;
  }

And similarly in the processing of "usermove" make it:
Code: Select all
      if (Options["UCI_AnalyseMode"] || ponderMove != "") // move received during search
      {
          Threads.stop = true;
          Threads.main()->wait_for_search_finished();
          if(ponderMove != "" && ponderMove != "stop") [ // ponder miss, take ponder move back
              undo_move(pos, moveList, states);
              ponderMove = "stop";
          }
          // do not clear ponderMove yet, to cause ignoring of the 'rejected' triggered by ponder stop
      }
User avatar
H.G.Muller
 
Posts: 3453
Joined: 16 Nov 2005, 12:02
Location: Diemen, NL

Re: Winboard janggi "OpeningBook" compatibility development

Postby janggi-korea » 14 Nov 2020, 13:43

The latest version of Winboard also had a move reject error. I hope this will be solved.
I applied the code, but I am having some problems with compiling. Please check.




xboard.cpp: In member function 'void XBoard::StateMachine::process_command(Position&, std::string, std::istringstream&, StateListPtr&)':
xboard.cpp:447:46: error: expression list treated as compound expression in initializer [-fpermissive]
447 | undo_move(pos, moveList, states);
| ^
xboard.cpp:447:25: warning: left operand of comma operator has no effect [-Wunused-value]
447 | undo_move(pos, moveList, states);
| ^~~
xboard.cpp:447:30: warning: right operand of comma operator has no effect [-Wunused-value]
447 | undo_move(pos, moveList, states);
| ^~~~~~~~
xboard.cpp:447:47: error: expected ',' before ';' token
447 | undo_move(pos, moveList, states);
| ^
| ,
xboard.cpp:447:47: error: expected identifier before ';' token
xboard.cpp:447:47: error: expected ']' before ';' token
447 | undo_move(pos, moveList, states);
| ^
| ]
xboard.cpp: In lambda function:
xboard.cpp:447:47: error: expected '{' before ';' token
xboard.cpp: In member function 'void XBoard::StateMachine::process_command(Position&, std::string, std::istringstream&, StateListPtr&)':
xboard.cpp:446:56: error: use of deleted function 'std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = std::deque<StateInfo>; _Dp = std::default_delete<std::deque<StateInfo> >]'
446 | if(ponderMove != "" && ponderMove != "stop") [ // ponder miss, take ponder move back
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
447 | undo_move(pos, moveList, states);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from C:/msys64/mingw64/include/c++/10.2.0/memory:83,
from tune.h:22,
from types.h:827,
from evaluate.h:24,
from xboard.cpp:22:
C:/msys64/mingw64/include/c++/10.2.0/bits/unique_ptr.h:468:7: note: declared here
468 | unique_ptr(const unique_ptr&) = delete;
| ^~~~~~~~~~
xboard.cpp: At global scope:
xboard.cpp:464:5: error: expected unqualified-id before 'else'
464 | } else
| ^~~~
xboard.cpp:467:1: error: expected declaration before '}' token
467 | } // namespace XBoard
| ^
search.cpp: In member function 'virtual void Thread::search()':
search.cpp:453:15: warning: declaration of 'failedHighCnt' shadows a member of 'Thread' [-Wshadow]
453 | int failedHighCnt = 0;
| ^~~~~~~~~~~~~
In file included from search.cpp:33:
thread.h:76:7: note: shadowed declaration is here
76 | int failedHighCnt;
| ^~~~~~~~~~~~~
make[2]: *** [<builtin>: xboard.o] Error 1
make[2]: *** Waiting for unfinished jobs....
make[2]: Leaving directory '/home/baek/Fairy-Stockfish-master/src'
make[1]: *** [Makefile:907: gcc-profile-make] Error 2
make[1]: Leaving directory '/home/baek/Fairy-Stockfish-master/src'
make: *** [Makefile:768: profile-build] Error 2
C:\msys64\mingw64\bin\strip.exe: 'stockfish.exe': No such file
mv: cannot stat 'stockfish.exe': No such file or directory

baek@DESKTOP-8EBTPEO MINGW64 ~
$
janggi-korea
 
Posts: 130
Joined: 18 Aug 2020, 12:12

Re: Winboard janggi "OpeningBook" compatibility development

Postby H.G.Muller » 14 Nov 2020, 13:57

O sorry, I made a typo, and put a bracker [ where there should have been a brace {
Code: Select all
          if(ponderMove != "" && ponderMove != "stop") { // ponder miss, take ponder move back

Compilers get very upset by that sort of thing, as braces need to be balanced, and omitting one changes the context for the entire remainder of the source file.
User avatar
H.G.Muller
 
Posts: 3453
Joined: 16 Nov 2005, 12:02
Location: Diemen, NL

Re: Winboard janggi "OpeningBook" compatibility development

Postby janggi-korea » 14 Nov 2020, 14:05

Compilation was successful. Thank you very much.

Could you possibly solve some of the code errors below?
It doesn't matter for engine creation. However, it is probably an error that occurred during the recent merge.





search.cpp: In member function 'virtual void Thread::search()':
search.cpp:453:15: warning: declaration of 'failedHighCnt' shadows a member of 'Thread' [-Wshadow]
453 | int failedHighCnt = 0;
| ^~~~~~~~~~~~~
In file included from search.cpp:33:
thread.h:76:7: note: shadowed declaration is here
76 | int failedHighCnt;
| ^~~~~~~~~~~~~
janggi-korea
 
Posts: 130
Joined: 18 Aug 2020, 12:12

Re: Winboard janggi "OpeningBook" compatibility development

Postby H.G.Muller » 14 Nov 2020, 14:19

I don't know enough about Stockfish to fix that without running the risk of breaking it. It warns that two variables treated as different have the same name. This complaint can be made to go away by changing the name of one of those to something else, everywhere it is referred to. Then they will be different variables with different names. But perhaps they were intended to be the same variable. In that case the 'int' in front of one of those should be deleted, because that is what orders the creation of a new variable.
User avatar
H.G.Muller
 
Posts: 3453
Joined: 16 Nov 2005, 12:02
Location: Diemen, NL

PreviousNext

Return to Winboard and related Topics

Who is online

Users browsing this forum: No registered users and 32 guests