Kempelen wrote:Hello,
I am near to release my engine. At the moment it goes good with xboard, but I have implemented a draft uci handle module, but I dont like UCI. In each move, the GUI send something like:
position startpos moves e2e4 e7e6 g1f3 d7d5 e4d5 e6d5 d2d4 b8c6 c2c4 f8b4 b1c3
For my undestanding, this is very ugly. I dont clear hast tables between moves: my engine can transpose from one move to onother utilizing hash entries of previous searches. Also I store things like previus scores. The above strings force my to set a new position and make all moves in internal board without doing searches. Also I must clear the hash table, because if the move is a takeback, the age variable in the hash is newer and searhes will not going to overwrite.
I increase the age/date counter when a search starts on a new root position. No need to count backwards or ever clear the hash table unless asked: most things are explicit in uci. I only clear the table when "setoption name Clear Hash / isready" is sent.
I think "explicit" is a better description of UCI than "stateless". There is necessary state after "setoption", between "position" and "go" and between searches. It is just not as bad as with the original gnuchess on which the xboard protocol is based.
Code: Select all
rootSearch:
if (hash(board(self)) != self->lastSearched) {
we snip ...
self->lastSearched = hash(board(self));
self->tt.now = (self->tt.now + 1) & ones(ttDateBits);
}
Thinking about it now, it is probably safe to remove the entire condition and increase the counter unconditionally.
Also, if I dont store scores, I will not able to calculate learning values for my book handling (By the way, I would like to handle the book and learning values, and not the GUI).
In my case book learning is now done outside the engine, but I can live with that because that is a different domain anyhow. I can now use the same system ("bookie") for the different engines I have, even ones I didn't write myself. I appreciate the modularity and separation of concerns in that respect.
There are also other issues related to this way to handle UCI. At first sign, I really dont like the protocol.
Could someone point a correct way to handle this issues?
are you like me: dont like UCI? or am I the only that see bad things in it.
why is it so popular in top engines?
Adoption has not much to do with that is theoretically possible or what looks better when you inspect the data stream. Adoption is a result of how the entire eco system behaves. The protocol design can influence that but rarely decisively.
Both chess engine protocols have their pros and cons, but here clearly less is more: with uci you have a fully supported implementation up and running much quicker and the engine can be used in all interfaces for all common use cases, which is very nice for users: one executable, no engine ini files in their own format, no command line options, and books fully under control of the user. Some of these nasty things are not mandated by the line protocol but is how the xboard engines of the time had to be managed, while uci offered more uniformity (and stronger engines and nicer GUIs).
What I think is quite elegant in the uci design is that with just one pair of simple commands ("position" and "go") an uci engine can already make moves in a game, accept take back, setup and play from a new position, swap sides, accept new time controls, reset and start a new game and analyse random positions. Some of these things many xboard engines still can't do right. Heck, they can't agree on mate scores, or even the evaluation sign, and to solve that as a user you have to tick the right box. You know you have a design problem when you have to expose an internal matter to the end user.
The other helpful thing, from adoption point of view, is that the uci protocol is stable as a rock: It doesn't get more and more convoluted all the time. For example, the feature negotiation system added to xboard protocol v2 is truly horrible. If you want to drive an engine it is extremely annoying to parse with its multi-line / single-line variants of the "feature" command with no added value. And it has gems such as
"There are ten different options types, each requiring a slightly different syntax of the defining string". Also, as an engine programmer, you have really no idea what to do if a feature you need is "rejected" by the GUI. Options should be one-way and stupendously simple, and uci got both right. It made many design choices for you already instead of trying to be kind to everyone. As a result of its simplicity, all GUIs that matter today support uci and still not all GUIs support xboard. (Ironically, the two main shortcomings of the xboard protocol are its complexity and its GUI adoption rate. And with every amendment it gets more complex and its adoption rate drops.)
From an engine programmer's point of view some functionality is obviously missing in uci, but "out there" those just don't matter as much as we engine programmers believe.
In short: What mattered is what the end users liked, and they liked 1. the strongest engines, 2. the nicest GUIs without hassle, 3. ultimate control on how the game is started (openings) and stopped (adjudication), 4. smooth analysis. For them the uci eco system did all of those better than the xboard eco system. Even gnuchess, whose original commands the xboard protocol mimics, now doesn't support its "own" protocol anymore.
About liking or not liking, it is really secondary: SMK, who created uci, said he would like to do uci in a totally different way if it had to be done today, for example based on JSON, but that such is obviously not possible anymore. And that he himself recently got some of the UCI basics, namely the "id" responses to the "uci" command, completely wrong in his upcoming rewrite of Shredder