Page 1 of 13

UCCI2WB

Posted: Mon Oct 27, 2014 10:39 pm
by hgm
Now that Evert has made this nice overview of UCI dialects, I figured I might as wel try to make UCI2WB support all of this. It already supported UCI, SSI and the cyclone dialect of UCI, so the challenge is to add UCC.

Code: Select all

Nomenclature:

 UCI:
   players are called "white" and "black". White begins.
   squares are labelled a1,b1,...g8,h8, from lower left to upper right.

 USI:
   players are called "white" and "black". Black begins.
   squares are labelled 9i,8i...2a,1a, from lower left to upper right.

From GUI to engine
------------------

* uci, usi, ucci
	tell engine to use the uci (universal chess interface) or one of its
   dialects, this will be sent once as a first command after program boot
	to tell the engine to switch to uci mode.
	After receiving the uci command the engine must identify itself with the "id" command
	and send the "option" commands to tell the GUI which engine settings the engine supports if any.
	After that the engine should send "uciok" ("usiok", "ucciok") to acknowledge the uci mode.
	If no uciok is sent within a certain time period, the engine task will be killed by the GUI.

   In ucci mode, the list of options should at least include
      "option usemillisec type check default false"
      "option newgame type button"

* debug [ on | off ]
	switch the debug mode of the engine on and off.
	In debug mode the engine should send additional infos to the GUI, e.g. with the "info string" command,
	to help debugging, e.g. the commands that the engine has received etc.
	This mode should be switched off by default and this command can be sent
	any time, also when the engine is thinking.

* isready
	this is used to synchronize the engine with the GUI. When the GUI has sent a command or
	multiple commands that can take some time to complete,
	this command can be used to wait for the engine to be ready again or
	to ping the engine to find out if it is still alive.
	E.g. this should be sent after setting the path to the tablebases as this can take some time.
	This command is also required once before the engine is asked to do any search
	to wait for the engine to finish initializing.
	This command must always be answered with "readyok" and can be sent also when the engine is calculating
	in which case the engine should also immediately answer with "readyok" without stopping the search.

* setoption name <id> &#91;value <x>&#93;         &#40;UCI, USI&#41;
	this is sent to the engine when the user wants to change the internal parameters
	of the engine. For the "button" type no value is needed.
	One string will be sent for each parameter and this will only be sent when the engine is waiting.
	The name and value of the option in <id> should not be case sensitive
   and can inlude spaces in UCI &#40;but not in USI&#41;.
	The substrings "value" and "name" should be avoided in <id> and <x> to allow unambiguous parsing,
	for example do not use <name> = "draw value".
	Here are some strings for the example below&#58;
	   "setoption name Nullmove value true\n"
      "setoption name Selectivity value 3\n"
	   "setoption name Style value Risky\n"
	   "setoption name Clear Hash\n"
	   "setoption name NalimovPath value c&#58;\chess\tb\4;c&#58;\chess\tb\5\n"

* setoption <id> &#91;<x>&#93;         &#40;UCCI&#41;
	this is sent to the engine when the user wants to change the internal parameters
	of the engine. For the "button" type no value is needed.
	One string will be sent for each parameter and this will only be sent when the engine is waiting.
	The name and value of the option in <id> should not be case sensitive and can NOT inlude spaces.
   The name should preferentially be all in lower case.
	Here are some strings for the example below&#58;
	   "setoption nullmove true\n"
      "setoption selectivity 3\n"
	   "setoption style Risky\n"
	   "setoption clear Hash\n"
	   "setoption nalimovpath c&#58;\chess\tb\4;c&#58;\chess\tb\5\n"

* register
	this is the command to try to register an engine or to tell the engine that registration
	will be done later. This command should always be sent if the engine	has sent "registration error"
	at program startup.
	The following tokens are allowed&#58;
	* later
	   the user doesn't want to register the engine now.
	* name <x>
	   the engine should be registered with the name <x>
	* code <y>
	   the engine should be registered with the code <y>
	Example&#58;
	   "register later"
	   "register name Stefan MK code 4359874324"

* ucinewgame, usinewgame      &#40;UCI, USI&#41;
   this is sent to the engine when the next search &#40;started with "position" and "go") will be from
   a different game. This can be a new game the engine should play or a new game it should analyse but
   also the next position from a testsuite with positions only.
   If the GUI hasn't sent a "ucinewgame" before the first "position" command, the engine shouldn't
   expect any further ucinewgame commands as the GUI is probably not supporting the ucinewgame command.
   So the engine should not rely on this command even though all new GUIs should support it.
   As the engine's reaction to "ucinewgame" can take some time the GUI should always send "isready"
   after "ucinewgame" to wait for the engine to finish its operation.

* setoption newgame           &#40;UCCI&#41;
   See usinewgame above.
   Note that the engine most define this option for it to be sent.

* position &#91;fen <fenstring> | startpos &#93;  moves <move1> .... <movei>    &#40;UCI&#41;
	set up the position described in fenstring on the internal board and
	play the moves on the internal chess board.
	if the game was played  from the start position the string "startpos" will be sent
	Note&#58; no "new" command is needed. However, if this position is from a different game than
	the last position sent to the engine, the GUI should have sent a "ucinewgame" inbetween.

* fen <fenstring> moves <move1> .... <movei>    &#40;UCI-cyclone&#41;
   As "position fen" above.

* position &#91;sfen <fenstring> | startpos &#93;  moves <move1> .... <movei>   &#40;USI&#41;
   as above, but sends sfen rather than FEN. Moves use Shogi-style square
   names.
   To be safe, it is better to not use startpos at all &#40;not all engines
   understand it&#41; and always set the postion using a FEN string.

* position fen <fenstring> moves <move1> .... <movei>                   &#40;UCCI&#41;
   as above. Uses normal FEN for Xiangqi &#40;with piece names RNBACPK&#41;. Moves
   use Western-style square names. The square on the lower-left hand side
   of the first player ("white") is "a0", the upper-right is "i9".
   The FEN string includes fields for en-passant and castling &#40;both -,
   obviously&#41;.
   Normally, the interface is expected to send the FEN for the position
   after the last irreversible move, and the move history from that point
   onward. This to reduce the amount of traffic between engine and GUI.
   Note there is no "startpos"!

* probe &#91; fen <fenstring> | startpos &#93; moves <move1> .... <movei> &#40;UCCI&#41;
   Tell the engine to spit out whatever it found about the current position
   in its hash table &#40;using the "pophash" response&#41;. Apparently for
   debugging only. For some reason "startpos" is possible here &#40;probably a
   mistake&#41;.

* banmoves <move1> .... <movei>  &#40;UCCI&#41;
   exclude the listed moves from consideration in the current position.
   This is useful for analysis, but the GUI may also use this to send moves
   that represent illegal chases. This allows engines to not implement the
   &#40;full&#41; chasing rules, and rely on the GUI instead.

* go                             &#40;UCI, USI, UCCI&#41;
	start calculating on the current position set up with the "position" command.
	There are a number of commands that can follow this command, all will be sent in the same string.
	If one command is not sent its value should be interpreted as it would not influence the search.
	* searchmoves <move1> .... <movei>
		restrict search to this moves only
		Example&#58; After "position startpos" and "go infinite searchmoves e2e4 d2d4"
		the engine should only search the two moves e2e4 and d2d4 in the initial position.
   * draw         &#40;UCCI&#41;
      ???
      I *think* this is meant to be a draw offer.
	* ponder
		start searching in pondering mode.
		Do not exit the search in ponder mode, even if it's mate!
		This means that the last move sent in in the position string is the ponder move.
		The engine can do what it wants to do, but after a "ponderhit" command
		it should execute the suggested move to ponder on. This means that the ponder move sent by
		the GUI can be interpreted as a recommendation about which move to ponder. However, if the
		engine decides to ponder on a different move, it should not display any mainlines as they are
		likely to be misinterpreted by the GUI because the GUI expects the engine to ponder
	   on the suggested move.
	* wtime <x>          &#40;UCI, USI&#41;
		white has x msec left on the clock
	* btime <x>          &#40;UCI, USI&#41;
		black has x msec left on the clock
	* winc <x>           &#40;UCI, USI&#41;
		white increment per move in mseconds if x > 0
	* binc <x>           &#40;UCI, USI&#41;
		black increment per move in mseconds if x > 0
	* movestogo <x>
      there are x moves to the next time control,
		this will only be sent if x > 0,
		if you don't get this and get the wtime and btime it's sudden death
   * time <x>           &#40;UCCI&#41;
      side to move has x left on the clock
      x is in s, unless the GUI has sent "option usemillisec true", in
      which case it is msec
   * opptime <x>        &#40;UCCI&#41;
      side not on move has x left on the clock
      x is in s, unless the GUI has sent "option usemillisec true", in
      which case it is msec
	* increment <x>      &#40;UCCI&#41;
		side-to-move increment per move in s or msec
	* oppincrement <x>   &#40;UCCI&#41;
		not side-to-move increment per move in s or msec
	* oppmovestogo <x>   &#40;UCCI&#41;
      the opponent has x moves to the next time control
	* depth <x>
		search x plies only.
	* nodes <x>
	   search x nodes only,
	* mate <x>
		search for a mate in x moves
	* movetime <x>
		search exactly x mseconds
        * byoyomi <x>        &#40;USI&#41;
		search exactly x mseconds if the time &#40;specified by
      wtime/btime&#41; has been used up
	* infinite
		search until the "stop" command. Do not exit the search without being told so in this mode!

* stop
	stop calculating as soon as possible,
	don't forget the "bestmove" and possibly the "ponder" token when finishing the search

* ponderhit
	the user has played the expected move. This will be sent if the engine was told to ponder on the same move
	the user has played. The engine should continue searching but switch from pondering to normal search.

* ponderhit draw        &#40;UCCI&#41;
	Accept a draw offer while pondering.

* quit
	quit the program as soon as possible

* bye                   &#40;UCCI&#41;
   finish the calculation, then quit




Engine to GUI&#58;
--------------

* id
	* name <x>
		this must be sent after receiving the "uci" command to identify the engine,
		e.g. "id name Shredder X.Y\n"
	* author <x>
		this must be sent after receiving the "uci" command to identify the engine,
		e.g. "id author Stefan MK\n"

* uciok
	Must be sent after the id and optional options to tell the GUI that the engine
	has sent all infos and is ready in uci mode.

* readyok
	This must be sent when the engine has received an "isready" command and has
	processed all input and is ready to accept new commands now.
	It is usually sent after a command that can take some time to be able to wait for the engine,
	but it can be used anytime, even when the engine is searching,
	and must always be answered with "isready".

* bestmove <move1> &#91; ponder <move2> &#93;
	the engine has stopped searching and found the move <move> best in this position.
	the engine can send the move it likes to ponder on. The engine must not start pondering automatically.
	this command must always be sent if the engine stops searching, also in pondering mode if there is a
	"stop" command, so for every "go" command a "bestmove" command is needed!
	Directly before that the engine should send a final "info" command with the final search information,
	the the GUI has the complete statistics about the last search.

* bestmove &#91; draw | resign &#93;  &#40;UCCI&#41;
   the engine accepts a draw offer, or resigns.

* nobestmove         &#40;UCCI&#41;
   The search returned no move. Either there are no legal moves &#40;the game
   ended&#41;, or the engine was interrupted before it could produce a move.
   Also sent in response to "go depth 0", which prompts the engine to spit
   out its static evaluation of the current position.

* pophash &#91;bestmove <move>&#93; &#91;lowerbound <beta> depth <depth>&#93; &#91;upperbound <alpha> depth <depth>&#93;   &#40;UCCI&#41;
   Response to "probe". Whatever the engine found in its transposition
   table for the current position. Again apparetly meant as a debugging
   aid.
   If the position was not found, leave all fields blank.

* copyprotection
	this is needed for copyprotected engines. After the uciok command the engine can tell the GUI,
	that it will check the copy protection now. This is done by "copyprotection checking".
	If the check is ok the engine should send "copyprotection ok", otherwise "copyprotection error".
	If there is an error the engine should not function properly but should not quit alone.
	If the engine reports "copyprotection error" the GUI should not use this engine
	and display an error message instead!
	The code in the engine can look like this
      TellGUI&#40;"copyprotection checking\n");
	   // ... check the copy protection here ...
	   if&#40;ok&#41;
	      TellGUI&#40;"copyprotection ok\n");
      else
         TellGUI&#40;"copyprotection error\n");

* registration
	this is needed for engines that need a username and/or a code to function with all features.
	Analog to the "copyprotection" command the engine can send "registration checking"
	after the uciok command followed by either "registration ok" or "registration error".
	Also after every attempt to register the engine it should answer with "registration checking"
	and then either "registration ok" or "registration error".
	In contrast to the "copyprotection" command, the GUI can use the engine after the engine has
	reported an error, but should inform the user that the engine is not properly registered
	and might not use all its features.
	In addition the GUI should offer to open a dialog to
	enable registration of the engine. To try to register an engine the GUI can send
	the "register" command.
	The GUI has to always answer with the "register" command	if the engine sends "registration error"
	at engine startup &#40;this can also be done with "register later")
	and tell the user somehow that the engine is not registered.
	This way the engine knows that the GUI can deal with the registration procedure and the user
	will be informed that the engine is not properly registered.


* info
	the engine wants to send information to the GUI. This should be done whenever one of the info has changed.
	The engine can send only selected infos or multiple infos with one info command,
	e.g. "info currmove e2e4 currmovenumber 1" or
	     "info depth 12 nodes 123456 nps 100000".
	Also all infos belonging to the pv should be sent together
	e.g. "info depth 2 score cp 214 time 1242 nodes 2124 nps 34928 pv e2e4 e7e5 g1f3"
	I suggest to start sending "currmove", "currmovenumber", "currline" and "refutation" only after one second
	to avoid too much traffic.
	Additional info&#58;
	* depth <x>
		search depth in plies
	* seldepth <x>
		selective search depth in plies,
		if the engine sends seldepth there must also be a "depth" present in the same string.
	* time <x>
		the time searched in ms, this should be sent together with the pv.
	* nodes <x>
		x nodes searched, the engine should send this info regularly
	* pv <move1> ... <movei>
		the best line found
	* multipv <num>
		this for the multi pv mode.
		for the best move/pv add "multipv 1" in the string when you send the pv.
		in k-best mode always send all k variants in k strings together.
	* score
		* cp <x>
			the score from the engine's point of view in centipawns.
		* mate <y>
			mate in y moves, not plies.
			If the engine is getting mated use negative values for y.
		* lowerbound
	      the score is just a lower bound.
		* upperbound
		   the score is just an upper bound.
	* currmove <move>
		currently searching this move
	* currmovenumber <x>
		currently searching move number x, for the first move x should be 1 not 0.
	* hashfull <x>
		the hash is x permill full, the engine should send this info regularly
	* nps <x>
		x nodes per second searched, the engine should send this info regularly
	* tbhits <x>
		x positions where found in the endgame table bases
	* sbhits <x>
		x positions where found in the shredder endgame databases
	* cpuload <x>
		the cpu usage of the engine is x permill.
	* string <str>
		any string str which will be displayed be the engine,
		if there is a string command the rest of the line will be interpreted as <str>.
	* refutation <move1> <move2> ... <movei>
	   move <move1> is refuted by the line <move2> ... <movei>, i can be any number >= 1.
	   Example&#58; after move d1h5 is searched, the engine can send
	   "info refutation d1h5 g6h5"
	   if g6h5 is the best answer after d1h5 or if g6h5 refutes the move d1h5.
	   if there is no refutation for d1h5 found, the engine should just send
	   "info refutation d1h5"
		The engine should only send this if the option "UCI_ShowRefutations" is set to true.
	* currline <cpunr> <move1> ... <movei>
	   this is the current line the engine is calculating. <cpunr> is the number of the cpu if
	   the engine is running on more than one cpu. <cpunr> = 1,2,3....
	   if the engine is just using one cpu, <cpunr> can be omitted.
	   If <cpunr> is greater than 1, always send all k lines in k strings together.
		The engine should only send this if the option "UCI_ShowCurrLine" is set to true.
   * message <message>  &#40;UCCI&#41;
      Whatever other information the engine wants to tell the user. The GUI
      can display this somewhere.


* option
	This command tells the GUI which parameters can be changed in the engine.
	This should be sent once at engine startup after the "uci" and the "id" commands
	if any parameter can be changed in the engine.
	The GUI should parse this and build a dialog for the user to change the settings.
	Note that not every option needs to appear in this dialog as some options like
	"Ponder", "UCI_AnalyseMode", etc. are better handled elsewhere or are set automatically.
	If the user wants to change some settings, the GUI will send a "setoption" command to the engine.
	Note that the GUI need not send the setoption command when starting the engine for every option if
	it doesn't want to change the default value.
	For all allowed combinations see the examples below,
	as some combinations of this tokens don't make sense.
	One string will be sent for each parameter.
	* name <id>
		The option has the name id.
		Certain options have a fixed value for <id>, which means that the semantics of this option is fixed.
		Usually those options should not be displayed in the normal engine options window of the GUI but
		get a special treatment. "Pondering" for example should be set automatically when pondering is
		enabled or disabled in the GUI options. The same for "UCI_AnalyseMode" which should also be set
		automatically by the GUI. All those certain options have the prefix "UCI_" except for the
		first 6 options below. If the GUI gets an unknown Option with the prefix "UCI_", it should just
		ignore it and not display it in the engine's options dialog.
		* <id> = Hash, type is spin
			the value in MB for memory for hash tables can be changed,
			this should be answered with the first "setoptions" command at program boot
			if the engine has sent the appropriate "option name Hash" command,
			which should be supported by all engines!
			So the engine should use a very small hash first as default.
		* <id> = NalimovPath, type string
			this is the path on the hard disk to the Nalimov compressed format.
			Multiple directories can be concatenated with ";"
		* <id> = NalimovCache, type spin
			this is the size in MB for the cache for the nalimov table bases
			These last two options should also be present in the initial options exchange dialog
			when the engine is booted if the engine supports it
		* <id> = Ponder, type check
			this means that the engine is able to ponder.
			The GUI will send this whenever pondering is possible or not.
			Note&#58; The engine should not start pondering on its own if this is enabled, this option is only
			needed because the engine might change its time management algorithm when pondering is allowed.
		* <id> = OwnBook, type check
			this means that the engine has its own book which is accessed by the engine itself.
			if this is set, the engine takes care of the opening book and the GUI will never
			execute a move out of its book for the engine. If this is set to false by the GUI,
			the engine should not access its own book.
		* <id> = MultiPV, type spin
			the engine supports multi best line or k-best mode. the default value is 1
		* <id> = UCI_ShowCurrLine, type check, should be false by default,
			the engine can show the current line it is calculating. see "info currline" above.
		* <id> = UCI_ShowRefutations, type check, should be false by default,
			the engine can show a move and its refutation in a line. see "info refutations" above.
		* <id> = UCI_LimitStrength, type check, should be false by default,
			The engine is able to limit its strength to a specific Elo number,
		   This should always be implemented together with "UCI_Elo".
		* <id> = UCI_Elo, type spin
			The engine can limit its strength in Elo within this interval.
			If UCI_LimitStrength is set to false, this value should be ignored.
			If UCI_LimitStrength is set to true, the engine should play with this specific strength.
		   This should always be implemented together with "UCI_LimitStrength".
		* <id> = UCI_AnalyseMode, type check
		   The engine wants to behave differently when analysing or playing a game.
		   For example when playing it can use some kind of learning.
		   This is set to false if the engine is playing a game, otherwise it is true.
		 * <id> = UCI_Opponent, type string
		   With this command the GUI can send the name, title, elo and if the engine is playing a human
		   or computer to the engine.
		   The format of the string has to be &#91;GM|IM|FM|WGM|WIM|none&#93; &#91;<elo>|none&#93; &#91;computer|human&#93; <name>
		   Examples&#58;
		   "setoption name UCI_Opponent value GM 2800 human Gary Kasparov"
		   "setoption name UCI_Opponent value none none computer Shredder"
		 * <id> = UCI_EngineAbout, type string
		   With this command, the engine tells the GUI information about itself, for example a license text,
		   usually it doesn't make sense that the GUI changes this text with the setoption command.
		   Example&#58;
			"option name UCI_EngineAbout type string default Shredder by Stefan Meyer-Kahlen, see www.shredderchess.com"
		* <id> = UCI_ShredderbasesPath, type string
			this is either the path to the folder on the hard disk containing the Shredder endgame databases or
			the path and filename of one Shredder endgame datbase.
	   * <id> = UCI_SetPositionValue, type string
	      the GUI can send this to the engine to tell the engine to use a certain value in centipawns from white's
	      point of view if evaluating this specifix position. 
	      The string can have the formats&#58;
	      <value> + <fen> | clear + <fen> | clearall

	* type <t>
		The option has type t.
		There are 5 different types of options the engine can send
		* check
			a checkbox that can either be true or false
		* spin
			a spin wheel that can be an integer in a certain range
		* combo
			a combo box that can have different predefined strings as a value
		* button
			a button that can be pressed to send a command to the engine
		* string
			a text field that has a string as a value,
			an empty string has the value "<empty>"
	* default <x>
		the default value of this parameter is x
	* min <x>
		the minimum value of this parameter is x
	* max <x>
		the maximum value of this parameter is x
	* var <x>
		a predefined value of this parameter is x
	Examples&#58;
    Here are 5 strings for each of the 5 possible types of options
	   "option name Nullmove type check default true\n"
      "option name Selectivity type spin default 2 min 0 max 4\n"
	   "option name Style type combo default Normal var Solid var Normal var Risky\n"
	   "option name NalimovPath type string default c&#58;\\n"
	   "option name Clear Hash type button\n"



Common incompatibilities&#58;
-------------------------
UCI&#58;
   many variant engines &#40;Shogi, Xiangqi&#41; do not understand "startpos".

USI&#58;
   many engines only recognise the following format for the "go" command&#58;
   "go btime %d wtime %d byoyomi %d"
   The options winc/binc/movestogo/movetime may cause unpredictabe
   behaviour, including crashes.

   many engines only respond to "isready" once, and only allow options to
   be set before receiving "isready".

   Standard options &#40;hash, ponder&#41; are not announced, even if they do exist
   and can be set.

UCCI&#58;
   many engines do not accurately report the options they have. This is
   particularly problematic for "usemillisec".
   It is best to always set options explicitly and not trust the defaults.
In making the attempt I learned some more about UCCI, for which Elephant Eye is supposed to be the reference implementation:

*) "ponder" only seems to work when it directly follows "go".
*) "movestogo" seems to have a default of 1: if I omit it the engine uses up most of its wtime or btime.
*) I vaguely remember from discussing with other XQ engine authors that to do sudden death you need to give "movestogo 0".
*) It seems that "draw" cannot only be in the "bestmove" command in stead of a move, but also in addition to a move. I only have indirect evidence for this, but when I let UCI2WB scan the bestmove line for "draw" and put out a "1/2-1/2" result claim as transalation (assuming it received "bestmove draw", so the game had to be over), Elephant Eye suddenly claimed in a position that was neither a repeat nor 50-move, but did have a close-to-zero score. So I supsect it sent "bestmove MOVE draw ponder PMOVE" in that case, to offer a draw. (This would make sense; a draw offer is part of the move, logically.)

Re: UCCI2WB

Posted: Tue Oct 28, 2014 9:42 am
by Evert
Excellent! I was about to start a post on this here as well. I'm hoping more people will consider writing variant engines if they know how to do it with UCI (of course there needs to be a standard way to specify variants).

Although everyone could just adopt XBoard protocol instead, we're already seeing ad-hoc adaptations for UCI engines to play variants (like the Stockfish that plays king-of-the-hill) and we don't need any further proliferation of subtly different and incompatible UCI dialects (if we do, we should drop the U from the name).
hgm wrote: In making the attempt I learned some more about UCCI, for which Elephant Eye is supposed to be the reference implementation:

*) "ponder" only seems to work when it directly follows "go".
Do you mean "goponder" as opposed to "go ponder"?
*) "movestogo" seems to have a default of 1: if I omit it the engine uses up most of its wtime or btime.
*) I vaguely remember from discussing with other XQ engine authors that to do sudden death you need to give "movestogo 0".
Lovely incompatibility with UCI there.
*) It seems that "draw" cannot only be in the "bestmove" command in stead of a move, but also in addition to a move. I only have indirect evidence for this, but when I let UCI2WB scan the bestmove line for "draw" and put out a "1/2-1/2" result claim as transalation (assuming it received "bestmove draw", so the game had to be over), Elephant Eye suddenly claimed in a position that was neither a repeat nor 50-move, but did have a close-to-zero score. So I supsect it sent "bestmove MOVE draw ponder PMOVE" in that case, to offer a draw. (This would make sense; a draw offer is part of the move, logically.)
Ah, correct. The webpage actually says "bestmove <&#26368;&#20339;&#30528;&#27861;> [ponder <&#21518;&#21488;&#24605;&#32771;&#30340;&#29468;&#27979;&#30528;&#27861;>] [draw | resign]" ("bestmove <Best of France> [ponder <backstage thinking guess France>] [draw | resign]" according to Google).

Re: UCCI2WB

Posted: Tue Oct 28, 2014 11:19 am
by hgm
Evert wrote:Do you mean "goponder" as opposed to "go ponder"?
No, they must be separate words. It was just that when I sent

go time NNN opptime MMM movestogo 39 ponder

(as UCI2WB used to do), the 'ponder' seemed to be ignored completely, and Elephant Eye spontaneously produced a 'bestmove' after some time.
Ah, correct. The webpage actually says "bestmove <&#26368;&#20339;&#30528;&#27861;> [ponder <&#21518;&#21488;&#24605;&#32771;&#30340;&#29468;&#27979;&#30528;&#27861;>] [draw | resign]" ("bestmove <Best of France> [ponder <backstage thinking guess France>] [draw | resign]" according to Google).
OK, it has to come at the end. That is great; then I can simply strip it off after having seen it.

I guess that bestmove draw for claiming a draw actually isn't allowed at all. I am not sure that UCCI engines can claim, but it seems that if they want, it should fall under the nobestmove case.

What about offering the draw? UCI2WB currently sends

go draw time NNN opptime MMM ...

if it received an "offer draw" from the GUI since the previous search started. The implementaton might still be a bit flaky (in case of pondering).

Note I pushed my first attempt at supporting UCCI in UCI2WB to hgm.nubati.net.

Another thing:

I noticed that in the UCI Cyclone dialect I let UCI2WB send the FEN with "r" as side to move. I suppose there was a reason for that, although I don't remember. (It probably means the 'setboard' in UCI-XQ is broken, as it just passes on what the GUI sent.) In UCCI I now use the normal "w" and "b".

Re: UCCI2WB

Posted: Tue Oct 28, 2014 11:38 am
by Evert
hgm wrote: No, they must be separate words. It was just that when I sent

go time NNN opptime MMM movestogo 39 ponder

(as UCI2WB used to do), the 'ponder' seemed to be ignored completely, and Elephant Eye spontaneously produced a 'bestmove' after some time.
Ah, ok. It never occurred to me to send any other information with "go ponder". It doesn't seem useful.
OK, it has to come at the end. That is great; then I can simply strip it off after having seen it.

I guess that bestmove draw for claiming a draw actually isn't allowed at all. I am not sure that UCCI engines can claim, but it seems that if they want, it should fall under the nobestmove case.
Yes, makes sense. I guess the way to find out would be to feed EE a dead-drawn position and seeing if it tries to claim anything (then again, it may simply be intended as an offer…)
What about offering the draw? UCI2WB currently sends

go draw time NNN opptime MMM ...

if it received an "offer draw" from the GUI since the previous search started. The implementaton might still be a bit flaky (in case of pondering).
Looks good to me, but I have to admit that the protocol spec isn't so clear to me. It states that "go ponder" and "go draw" are mutually exclusive, but what that means isn't so obvious. I think it means that if it receives "go draw" the engine should stop pondering and enter a normal search (I think that's what the "English" translation means by "raise the engine to the options bestmove provided as feedback"), bearing in mind that it has received a draw offer. In the case of a ponder hit, the corresponding command is "ponderhit draw" (now updated my description to make this clearer).
What confuses me is that I would normally expect either

Code: Select all

go ponder
stop
go … moves …
or

Code: Select all

go ponder
ponderhit
depending on whether there was a ponder hit or not. What the description suggests is that "stop" is optional, and you could get

Code: Select all

go ponder
go &#91;draw&#93; … moves ...
EDIT: No, wait - what I think it means is that the combination "go draw ponder" makes no sense and should not be sent.

Re: UCCI2WB

Posted: Tue Oct 28, 2014 12:03 pm
by hgm
Evert wrote:Ah, ok. It never occurred to me to send any other information with "go ponder". It doesn't seem useful.
But it is essential, not? How else would the engine know how long it can think after it gets a 'ponderhit'?

This is actually the worst design flaw of UCI. Logically the wtime/btime/etc. should all have come with the 'ponderhit' command. Because there is no way to send a correct opponent time with the 'go ponder' command, as you don't know at that time how long the opponnet is gooing to think.
Looks good to me, but I have to admit that the protocol spec isn't so clear to me. It states that "go ponder" and "go draw" are mutually exclusive, but what that means isn't so obvious.
Well, it does seem to make sense to me, and I was actually worrying about it. Because in my current implementation it is possible that the engine gets "go ponder draw ..." if the draw offer came before it started pondering (i.e. during the search for its own move).

And this of course makes no sense; logically it should mean that it ponders based on a speculative draw offer coming together with the move it ponders on. And as it provided that move itself from the previous "bestmove-ponder", there isn't even a way it could indicate that, as a 'draw' suffix there means an immediate draw offer with the bestmove, not an expected draw offer with the ponder move.
I think it means that if it receives "go draw" the engine should stop pondering and enter a normal search (I think that's what the "English" translation means by "raise the engine to the options bestmove provided as feedback"), bearing in mind that it has received a draw offer. In the case of a ponder hit, the corresponding command is "ponderhit draw" (now updated my description to make this clearer).
If you suppose draw offers cannot come without a move, I think it makes perfect sense. Because you have the move, you know whether it was a hit. If not, you simply stop the search, and start a new, real one with "go draw", which it would also do with ponder off. On a ponderhit you send "ponderhit draw", so that "go ponder" + "ponderhit draw" now together do what "go ponder draw" would have meant (except that now you don't have to speculate about the offer).

Re: UCCI2WB

Posted: Tue Oct 28, 2014 3:32 pm
by JoshPettus
I gave it a try in xboard
xboard -fcp "~~/../../UCI2WB -x /dir/Eleeye /dir"

and it told me UCI2WB exited unexpectedly

I tried it in a terminal and i think it runs, I can't get it to spew anything debug flag or no. But it stays open until I type exit and it quits.
EDIT - it quits without warning when i type in "new or go"

Code: Select all

go
# start search
# position fen 9/9/9/9/9/9/9/9/9/9 w - - 0 1 moves
# go time 0 opptime 0
myself$

This was with that mac compile of eleeye that worked when I typed ucci in terminal. (perhaps the engine isn't working after all?)[/code]

Re: UCCI2WB

Posted: Tue Oct 28, 2014 3:53 pm
by hgm
It is essential that you give the commands that would normally preceed it:

protover 2
new
variant xiangqi
go


It should at least echo you the command you just entered. If it doesn't do that, it is likely hanging, waiting for the engine to say something (like ucciok or readyok) before it is allowed to process further input. But if the thing it is waiting for would only be given by the engine in response to something sent in a command you did not give, (like protover causes sending of ucci) you are dead.

I think Elephant Eye exits if the first thing it receives is not 'ucci'. So you must start with protover.

Without 'variant xiangqi' the board would not be initialized, and an empty FEN would be sent, which the engine won't like either. I don't know what it would think of 'time 0'; you can prevent that by entering 'time 10000' and 'otim 10000' before 'go'.

I have a problem myself too, with ponder on:

Code: Select all

15444 <second&#58; # engine said&#58; bestmove h9g7 ponder h0g2
15444 <second&#58; # ponder on h0g2
15444 <second&#58; # position fen rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNBAKABNR w - - 0 1 moves h2e2 h9g7 h0g2
15444 <second&#58; # go ponder time 59984 opptime 59230 movestogo 39
15444 <second&#58; move h9g7
15585 <second&#58; # engine said&#58; info depth 0 score 640 pv i9h9
15585 <second&#58;   0     640      0          0 i9h9
15585 <second&#58; # engine said&#58; info depth 0 score 51 pv g6g5
15585 <second&#58;   0      51      0          0 g6g5
15585 <second&#58; # engine said&#58; info depth 0 score 35 pv b9c7
15585 <second&#58;   0      35      0          0 b9c7
15585 <second&#58; # engine said&#58; info depth 0 score 3 pv i9i8
15585 <second&#58;   0       3      0          0 i9i8
15585 <second&#58; # engine said&#58; info depth 0 score 1 pv b7e7
15585 <second&#58;   0       1      0          0 b7e7
15585 <second&#58; # engine said&#58; bestmove i9h9 ponder i0h0
15585 <second&#58; # ponder on i0h0
15585 <second&#58; # position fen rnbakabr1/9/1c4nc1/p1p1p1p1p/9/9/P1P1P1P1P/1C2C4/9/RNBAKABR1 w - - 0 1 moves
15585 <second&#58; # go ponder time 59952 opptime 59230 movestogo 38
15585 <second&#58; move i9h9
Ignoring move out of turn by second, gameMode 5, forwardMost 2
The engine gives a bestmove h9g7 and a ponder move h0g2. So UCI2WB sends the h9g7 to WinBoard, and sets the engine to ponder on h0g2 with a "go ponder" command.

Elephant Eye is still in book, however, and almost instantly replies with a bestmove for the book move it selects. But it should never do that during ponder. It should always wait for 'stop' or 'ponderhit' before giving that move. At least in UCI.

This looks like an engine bug.

Re: UCCI2WB

Posted: Tue Oct 28, 2014 4:01 pm
by JoshPettus
Hmm seems to work, though it doesn't echo the command back

Code: Select all

Joshuas-MacBook-Pro&#58;~ herecomethej$ /Applications/Chess/Xboard/XBoard.app/Contents/Resources/bin/UCI2WB debug -x /Applications/Chess/Engines/eleeye/ELEEYE /Applications/Chess/Engines/eleeye 
protover 2
feature variants="normal,xiangqi" setboard=1 usermove=1 debug=1 ping=1 reuse=0 exclude=1 pause=1 done=0
feature option="UCI2WB debug output -check 1"
# engine said&#58; id name ElephantEye
feature myname="ElephantEye &#40;UXI2WB&#41;"
# engine said&#58; id version 3.3
# engine said&#58; id copyright 2004-2012 www.xqbase.com
# engine said&#58; id author ElephantEye Development Team
# engine said&#58; id user ElephantEye Test Team
# engine said&#58; option usemillisec type check default true
# engine said&#58; option promotion type check default false
feature option="promotion -check 0"
# engine said&#58; option batch type check default false
feature option="batch -check 0"
# engine said&#58; option debug type check default false
feature option="debug -check 0"
# engine said&#58; option ponder type check default false
# engine said&#58; option usehash type check default true
feature option="usehash -check 1"
# engine said&#58; option usebook type check default true
feature option="usebook -check 1"
# engine said&#58; option bookfiles type string default ./BOOK.DAT
feature option="bookfiles -string ./BOOK.DAT"
# engine said&#58; option hashsize type spin min 16 max 1024 default 16
# engine said&#58; option idle type combo var none var small var medium var large default none
feature option="idle -combo none /// small /// medium /// large"
# engine said&#58; option pruning type combo var none var small var medium var large default large
feature option="pruning -combo none /// small /// medium /// large"
# engine said&#58; option knowledge type combo var none var small var medium var large default large
feature option="knowledge -combo none /// small /// medium /// large"
# engine said&#58; option randomness type combo var none var tiny var small var medium var large var huge default none
feature option="randomness -combo none /// tiny /// small /// medium /// large /// huge"
# engine said&#58; option newgame type button
# engine said&#58; ucciok
feature smp=1 memory=1 done=1
new
# engine said&#58; readyok
variant xiangqi
go
# start search
# position fen rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNBAKABNR w - - 0 1 moves
# go time 0 opptime 0
# engine said&#58; info depth 0 score 1473 pv b2e2
# engine said&#58; info depth 0 score 1473 pv h2e2
# engine said&#58; info depth 0 score 546 pv c3c4
# engine said&#58; info depth 0 score 546 pv g3g4
# engine said&#58; info depth 0 score 311 pv c0e2
# engine said&#58; info depth 0 score 311 pv g0e2
# engine said&#58; info depth 0 score 89 pv b0c2
# engine said&#58; info depth 0 score 89 pv h0g2
# engine said&#58; info depth 0 score 42 pv h2d2
# engine said&#58; info depth 0 score 42 pv b2f2
# engine said&#58; info depth 0 score 37 pv b2d2
# engine said&#58; info depth 0 score 37 pv h2f2
# engine said&#58; info depth 0 score 18 pv b0a2
# engine said&#58; info depth 0 score 18 pv h0i2
# engine said&#58; info depth 0 score 2 pv h2c2
# engine said&#58; info depth 0 score 2 pv b2g2
# engine said&#58; bestmove b2e2 ponder b9c7
move b2e2
Now i just have to figure out why it quits in xboard

Re: UCCI2WB

Posted: Tue Oct 28, 2014 4:05 pm
by JoshPettus
The xboard debug just has this

Code: Select all

StartChildProcess &#40;dir="/Applications/Chess/Xboard/XBoard.app/Contents/Resources/share/xboard/../../bin") /Applications/Chess/Xboard/XBoard.app/Contents/Resources/share/xboard/../../bin/UCI2WB -x /Applications/Chess/Engines/eleeye/ELEEYE /Applications/Chess/Engines/eleeye
6185 >first &#58; xboard
protover 2
6194 <first &#58; feature variants="normal,xiangqi" setboard=1 usermove=1 debug=1 ping=1 reuse=0 exclude=1 pause=1 done=0
6194 >first &#58; accepted variants
6194 >first &#58; accepted setboard
6194 >first &#58; accepted usermove
6194 >first &#58; accepted debug
6194 >first &#58; accepted ping
6194 >first &#58; accepted reuse
6194 >first &#58; accepted exclude
6194 >first &#58; accepted pause
6194 >first &#58; accepted done
6194 <first &#58; feature option="UCI2WB debug output -check 0"
6194 >first &#58; accepted option
And that's where it ends... Shouldn't it at least load?

Re: UCCI2WB

Posted: Tue Oct 28, 2014 4:15 pm
by hgm
Well, you should write '/bin/UCI2WB debug -x ...' to get some more output.

You are right, it does seem to wait for the engine to say something (in particular print its options and say 'ucciok', so it can send 'feature done=1' to XBoard), but nothing happens.