WinBoard/XBoard 4.8.0 released

Discussion of anything and everything relating to chess playing software and machines.

Moderators: hgm, Rebel, chrisw

User avatar
hgm
Posts: 27787
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: WinBoard/XBoard 4.8.0 released

Post by hgm »

Evert wrote:Apparently they tell you to set up the position after the last irreversible move instead of sending the entire game history at the start of every search, but that sounds more like an implementation detail in that you could do the same thing in an UCI interface. I have no idea what 1, 4 and 6 mean though.
Actually this sending of reversible moves only is the biggest stumbling block. Because you really have to do that, or most UCCI engines would crash after the 50th move of the game. (Silliest thing is that XQ doesn't even have a 50-move rule, officially...) Or perhaps it is UCCI2WB that crashes.

This means that UCI2WB could never do UCCI, because it is not aware of the game state. For UCCI the adapter really has to interpret the moves, to keep a board position, so that it can compose a FEN and send it to the engine. And if you want to implement 'undo' it even gets worse: you would have to remember all the FENs you ever used in that game, so that you can backup to before the FEN that you are currently using.

Whether it has to send 'name' or allows spaces in option names is only a minor difference compared to that.
User avatar
Evert
Posts: 2929
Joined: Sat Jan 22, 2011 12:42 am
Location: NL

Re: WinBoard/XBoard 4.8.0 released

Post by Evert »

Ok, here is my attempt at unifying the description for the various UCI dialects in one place. Note that I copied the UCI specification text and noted in the differences. I didn't include the description of the sfen or the move encoding in shogi.

Code: Select all

Nomenclature:

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

 USI:
   players are called "white" and "black". Black begins.
   squares are labelled 9i...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 true"
      "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"


* 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.

* 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.

* 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 analysis.

* 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
	* 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 offers a draw, 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.

* 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"
Some of the UCCI stuff is hard to interpret from the google translation. It seems like a curious mix of some good ideas (draw offer, ability to resign, nobestmove; I like the time <x> dynamic as well), some pointless changes (the name/value thing) and some seemingly pointless additions (probe/pophash).
User avatar
Evert
Posts: 2929
Joined: Sat Jan 22, 2011 12:42 am
Location: NL

Re: WinBoard/XBoard 4.8.0 released

Post by Evert »

hgm wrote: Actually this sending of reversible moves only is the biggest stumbling block. Because you really have to do that, or most UCCI engines would crash after the 50th move of the game. (Silliest thing is that XQ doesn't even have a 50-move rule, officially...) Or perhaps it is UCCI2WB that crashes.
Let's hope it's the latter, because then it can be fixed.

I guess you can even restrict more: send the last position (plus move list) where you know there was no chase situation. I guess that would allow you to keep the move list really short in practice.
This means that UCI2WB could never do UCCI, because it is not aware of the game state. For UCCI the adapter really has to interpret the moves, to keep a board position, so that it can compose a FEN and send it to the engine. And if you want to implement 'undo' it even gets worse: you would have to remember all the FENs you ever used in that game, so that you can backup to before the FEN that you are currently using.

Whether it has to send 'name' or allows spaces in option names is only a minor difference compared to that.
Well, not from my perspective as an engine developer. :P

There really is no way to work around that issue, unless you allow for a back-door (hidden or built in command) where you can ask XBoard to send you what it thinks the appropriate FEN string would be. Not pretty, but it may be the lesser of several evils.
User avatar
Evert
Posts: 2929
Joined: Sat Jan 22, 2011 12:42 am
Location: NL

Re: WinBoard/XBoard 4.8.0 released

Post by Evert »

JoshPettus wrote:Thanks, that worked! Though the line was originally:

Code: Select all

-DSVNVERSION=\\"$&#123;Project_WC_REVISION&#125;\\"")
Was it suppose to have put the version there automatically?
Yes, it works if the directory is actually a checkout, but not otherwise. I normally hard-code that line for release, but it seems I forgot to do that.
Is the development version out now? I didn't see it on your website.
It's not (yet). It's missing some features the old version had (user-configurable variants, analysis mode) and the evaluation is still pretty rough (strength-wise it's in the same ballpark, but it should be able to do a lot better with not too much effort). I'd also like to add in a better chase-detection for Xiangqi and maybe add a few more variants.
JoshPettus
Posts: 730
Joined: Fri Oct 19, 2012 2:23 am

Re: WinBoard/XBoard 4.8.0 released

Post by JoshPettus »

I see, thanks!

@HGM
when you get a chance, could you add the last couple of comments on Savannah master branch to your own branch? They deal with removing the OSX-theme and removing the gtk2-murrine engine references from the makefile.

Thanks!
User avatar
hgm
Posts: 27787
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: WinBoard/XBoard 4.8.0 released

Post by hgm »

Evert wrote:Ok, here is my attempt at unifying the description for the various UCI dialects in one place.
I strongly suspect that 'banmoves' is not just expected to work in analysis, but also in game play, to relieve engines from the duty of knowing the chasing rules.

There also is a 'Cyclone dialect' of UCI, which does not know the keyword 'startpos', (or perhaps considers it the start position of FIDE Chess) and leaves out the 'position' in "position fen".

Most Shogi and UCI engines I have seen are non-compliant with the standard in other respects. Often in such a consistent way that one could argue this defines a new dialect:

* Many USI engines do not understand 'winc' and 'binc', or even crash on receiving them.
* Instead they recognize a keyword 'byoyomi' on the 'go' command.
* USI engines can crash if you do not send 'wtime' and 'btime' in the order they expect. Or, indeed, when the 'go' command does not exactly conform to the pattern "go btime %d wtime %d byoyomi %d" (i.e. contains 'movestogo' or 'movetime', or swaps the order). Others just search by totally unpredictable amounts of time when they receive 'movestogo', 'winc' or 'binc' TCs.
* Many USI engines do respond to 'isready' ony once, and to 'setoption' only before that; receiving 'isready' obviously causes them to proceed to another command loop that does not decode these commands.
* They often do not announce standard USI options such as Hash and Ponder, even though they have a hash table (that can be set through setoption) and can ponder. (Chess UCI engines often sin in the latter way too, btw; Polyglot has the CanPonder work-around option for that.)

This could describe the 'Shogidogoro dialect'.

As for UCCI:
* Most engines do not issue 'option' commands, even if they have the options. In particular for standard option such as 'hashsize', but often not at all.
* Some announce options (like 'usemillisec') which they then turn out not to have; some announce the opposite default value for what they actually have.

A common sickness in all UCI-type engines is not being able to receive any commands between receiving 'stop' and sending 'bestmove'. Polyglot has the SyncStop work-around option for that.
User avatar
hgm
Posts: 27787
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: WinBoard/XBoard 4.8.0 released

Post by hgm »

JoshPettus wrote:@HGM
when you get a chance, could you add the last couple of comments on Savannah master branch to your own branch?
Ah sorry. I had not realized I was out of sync again.
User avatar
hgm
Posts: 27787
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: WinBoard/XBoard 4.8.0 released

Post by hgm »

Evert wrote:Let's hope it's the latter, because then it can be fixed.
Well, I doubt it, because not all engines seemed to do it.
There really is no way to work around that issue, unless you allow for a back-door (hidden or built in command) where you can ask XBoard to send you what it thinks the appropriate FEN string would be. Not pretty, but it may be the lesser of several evils.
Well, I could try to equip UCI2WB with game-state awareness just for the purpose of UCCI. XQ is a pretty straightforward game; moves cannot have side effects like e.p. capture, castling, promotion.

It would require having FEN reading (to interpret 'setboard') and writing code, though. The board it keeps could hold the piece IDs, though, so perhaps such code could be pretty simple. (It would not have to deal with complexities like holdings, castling rights or + prefixes.) That it makes a complete mess in any other variant than XQ would not matter, as the board would only be used for anything in UCCI mode.

The procedure for sending position-moves in UCCI mode would then be to run through the entire move list of the game, updating the board by strict from->to moving, identifying the last capture. And then, do it again but now only upto that last capture. And finally send 'position fen' for the internal board, followed by the rest of the move list. That is pretty simple, and perhaps simpler than making UCCI2WB work properly in Linux. The bulkiest part of the extra code would be the Board2FEN and FEN2Board routines (but hardly rocket science). But ignoring castling & e.p. field and move counters would simplify that too.
User avatar
Evert
Posts: 2929
Joined: Sat Jan 22, 2011 12:42 am
Location: NL

Re: WinBoard/XBoard 4.8.0 released

Post by Evert »

hgm wrote: I strongly suspect that 'banmoves' is not just expected to work in analysis, but also in game play, to relieve engines from the duty of knowing the chasing rules.
Ah, that makes sense. It does make things a lot more tricky though.
I'm not really sure if it's a good thing to not let engines implement the rules correctly though...
There also is a 'Cyclone dialect' of UCI, which does not know the keyword 'startpos', (or perhaps considers it the start position of FIDE Chess) and leaves out the 'position' in "position fen".
Well, there is no real reason to use "startpos" at all when you think about it (you can just always send the startup FEN). What's more annoying is not knowing whether to send "position fen" or just "fen" to an engine - particularly since UCI has no way for the engine to communicate this back to the GUI. On the other hand, I think UCI would allow you to send both, just in case (the engine should ignore what it doesn't understand; doesn't quite work in Sjaak, which still understands (almost) all XBoard commands in UCI mode).
* Many USI engines do not understand 'winc' and 'binc', or even crash on receiving them.
* Instead they recognize a keyword 'byoyomi' on the 'go' command.
What does it mean?
* USI engines can crash if you do not send 'wtime' and 'btime' in the order they expect. Or, indeed, when the 'go' command does not exactly conform to the pattern "go btime %d wtime %d byoyomi %d" (i.e. contains 'movestogo' or 'movetime', or swaps the order). Others just search by totally unpredictable amounts of time when they receive 'movestogo', 'winc' or 'binc' TCs.
Ah, I didn't mention that (or, come to think of it, implement it), but I guess the meaning of "wtime" and "btime" is swapped in USI compared to UCI, right?
* Many USI engines do respond to 'isready' ony once, and to 'setoption' only before that; receiving 'isready' obviously causes them to proceed to another command loop that does not decode these commands.
* They often do not announce standard USI options such as Hash and Ponder, even though they have a hash table (that can be set through setoption) and can ponder. (Chess UCI engines often sin in the latter way too, btw; Polyglot has the CanPonder work-around option for that.)
Well, I guess one could get the impression that these are "standard" options that should always be assumed to be there, whether the engine reports them or not. I certainly had the impression that UCI strongle encourages me to define those options (but still, I have to define them).
As for UCCI:
* Most engines do not issue 'option' commands, even if they have the options. In particular for standard option such as 'hashsize', but often not at all.
* Some announce options (like 'usemillisec') which they then turn out not to have; some announce the opposite default value for what they actually have.
Well, I guess as a GUI you can always not believe the default an engine tells you it had and just set it to what you want it to be. Means you don't have to check what it was before either.
Engines not having options that they claim they do is really awful behaviour though, but not something that the protocol specs can do anything to fix. It just makes a protocol utterly useless by comparison.

Note that Sjaak wouldn't understand time in seconds, so it's not exactly a paragon of correct behaviour.

Anyway, I'll add this information to my writeup. I guess it's much harder from the GUI-side (where you have to deal with non-compliant engines) than it is from the engine-side.
User avatar
hgm
Posts: 27787
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: WinBoard/XBoard 4.8.0 released

Post by hgm »

Evert wrote:Ah, that makes sense. It does make things a lot more tricky though.
I'm not really sure if it's a good thing to not let engines implement the rules correctly though...
I am sure it is a very bad idea. But I guess that Morning Yellow's philosophy was that the full chasing rules are extremely intimidating, and that it would discourage fewer beginning engine authors to tackle XQ if they could ignore the problem without being forfeited for perpetual chasing all the time. (Even if that would mean playing a bad move now and then.)
On the other hand, I think UCI would allow you to send both, just in case
Expecting this kind of compliancy is unfortunately asking way too much for XQ engines. The UCI engines I encountered simply would not move when you included the 'position' keyword (or used 'startpos'). The problem is that Cyclone has a status in XQ comparable to Shredder in Chess. It came with a GUI that became quite popular, and this GUI uses this dialect. The problem is that most people develop their eingine not to be compliant with a protocol spec, but just to work on one particular GUI. (There also exist WB engines that do not work in WinBoard, but only in Arena.)
What does it mean?
Biyoyomi is the traditional Japanese way of timing games, where you get a fixed initial time in which you don't have to move at all, if you don't want, after which a fixed-max-time-per-move (the 'biyoyomi') applies. So with 1 hour, 3-min byoyomi, you can make as many moves as you want in the first hour, (including 0), but you will have to make 1 move between 1:00 and 1:03, after which your clock resets to 0:03. WinBoard does not implement this TC, and (like any fixed-max-time-per-move TC) it is very detrimental to engine play, so I don't really feel like implementing it. Perhaps there will ever be a multi-session TC on XBoard, where you could specify the first session as 'time/game', which would then not imply sudden death if another session follows, and that other session could be a fixed-max-time-per-move, to implement biyoyomi.
Ah, I didn't mention that (or, come to think of it, implement it), but I guess the meaning of "wtime" and "btime" is swapped in USI compared to UCI, right?
Of course. It is a disease... Give a Shogi player something he could use, and the first thing he does it make it incompatible with everything else by swapping white and black. This is also the main difference between XBoard and xShogi protocol. GNU Chess even has a comment in the command parser that says "skip trailing black space"! :lol:
Well, I guess one could get the impression that these are "standard" options that should always be assumed to be there, whether the engine reports them or not. I certainly had the impression that UCI strongle encourages me to define those options (but still, I have to define them).
Sort of. The main reason is poor GUI design. The GUIs people develop for usually don't have an Engine Settings dialog (standard interactive GUI-design kits do not allow you to design anything for which the layout is not known in advance), and they solve the problem of engine options by having an ini file for each engine, the contents of which is unconditionally sent to the engine at startup. So it works anyway, whether the engine announces the options or not, as long as the user knows which options the engine has (e.g. because he can read the Chinese README file). For standard options these GUIs often send them just on their own initiative, in several flavors (like 'hash' as well as 'hashsize').
Well, I guess as a GUI you can always not believe the default an engine tells you it had and just set it to what you want it to be. Means you don't have to check what it was before either.
Indeed. It fits in the "GUI ignores the engine and sends whatever it wants" pattern.
Engines not having options that they claim they do is really awful behaviour though, but not something that the protocol specs can do anything to fix. It just makes a protocol utterly useless by comparison.
I guess the culprit here is that the Elephant Eye protocol-driver code was put in the public domain (although the rest of the code is GPL), to encourage people using the protocol. So many people just copied the code for their engine, not caring that it announced options that were implemented in Elephant Eye but not in their own engine. And never being punished for it, because the GUI they were using would ignore what the engine was saying anyway, and the options they did have would be set from the ini file they provided anyway.

In UCI2WB I made a work-around feature for these kind of problem, where a file DefectiveEngineOptions.ini in the engine folder would be read at engine startup as if the engine had sent its contents. There you can supply all options the engine should have sent (and because XBoard gets those first, you can even define duplicats with the correct default, whcih it would find before the ones the engine actually sent when searching through the option table).
Anyway, I'll add this information to my writeup. I guess it's much harder from the GUI-side (where you have to deal with non-compliant engines) than it is from the engine-side.
Perhaps. Or perhaps only until you also want your engine to work on these Chinese GUIs like Cyclone or Bing He Wu Si...