Page 1 of 1

Getting Engine to Communicate With WinBoard

PostPosted: 01 Sep 2010, 04:04
by beneficii
I'm working on an engine, and I have the board representation done, the evaluation done, the searches done, but now I'm trying to set up communication with WinBoard, and I've never done something like that before. It is said that you must communicate via pipes, but in reality the engine would just communicate via stdin and stdout, right? So, do you have something that just keeps checking stdin over and over again until it gets input, and then it acts on that? You have to make sure the buffer is cleared too, so you get every character, right? Then, when your engine needs to communicate with WinBoard, you print the commands on stdout and flush that buffer, right?

I'm writing it in C++. Is there a good library for this available, or will I have to take it like a ninja and write it all from scratch? What are some common pitfalls?

EDIT: I'm not sure where this topic should go; please move it if necessary. Thanks.

Re: Getting Engine to Communicate With WinBoard

PostPosted: 01 Sep 2010, 09:08
by H.G.Muller
You seem to understand quite well how it works. "Keep checking stdin" is in effect what input calls like getchar() always do: they do not return unless there is input (i.e. they block if there is no input). It is when you don't want that, (e.g. during pondering) that you have to take special action to know if there is input, without blocking if there isn't. In Wndows there is the PeekNamedPipe call for that.

And, like you say, any buffering would be fatal. Caling fflush(stdout) after printing anything, or even just before you start reading the next input line, is usually good enough to prevent any deadlocks, though. But to get real-time reporting of the engine depth, scores and PVs, you should imemdiatey flush those too.

Re: Getting Engine to Communicate With WinBoard

PostPosted: 01 Sep 2010, 09:41
by Matthias Gemuh
beneficii wrote:I'm working on an engine, and I have the board representation done, the evaluation done, the searches done, but now I'm trying to set up communication with WinBoard, and I've never done something like that before. It is said that you must communicate via pipes, but in reality the engine would just communicate via stdin and stdout, right? So, do you have something that just keeps checking stdin over and over again until it gets input, and then it acts on that? You have to make sure the buffer is cleared too, so you get every character, right? Then, when your engine needs to communicate with WinBoard, you print the commands on stdout and flush that buffer, right?

I'm writing it in C++. Is there a good library for this available, or will I have to take it like a ninja and write it all from scratch? What are some common pitfalls?

EDIT: I'm not sure where this topic should go; please move it if necessary. Thanks.


StdIn = GetStdHandle(STD_INPUT_HANDLE);
StdOut = GetStdHandle(STD_OUTPUT_HANDLE);
setbuf(stdout, NULL);
setvbuf(stdout, NULL, _IONBF, 0);

Then use StdIn/StdOut in ReadFile()/WriteFile(). Peep into input pipe with PeekNamedPipe().

Re: Getting Engine to Communicate With WinBoard

PostPosted: 03 Sep 2010, 03:50
by beneficii
So like:

void check_input() {
StdIn = GetStdHandle(STD_INPUT_HANDLE);
if(PeekNamePipe(StdIn))
DoCommand(ReadFile(StdIn));
return;
}

void write_output(char* command) {
StdOut = GetStdHandle(STD_OUTPUT_HANDLE);
setbuf(stdout, NULL);
WriteFile(StdOut, command);
return;
}

Now I know I'm missing some arguments on some of the functions, but that's the basic idea right?

Re: Getting Engine to Communicate With WinBoard

PostPosted: 03 Sep 2010, 09:44
by H.G.Muller
I guess you would have to do the setbuf only once, at program initialization. But it would not hurt to repeat it.

Re: Getting Engine to Communicate With WinBoard

PostPosted: 03 Sep 2010, 14:30
by beneficii
Also, how often should I check for input? Should I check on every node, or would that take too much time?

Re: Getting Engine to Communicate With WinBoard

PostPosted: 03 Sep 2010, 15:20
by Robert Pope
beneficii wrote:Also, how often should I check for input? Should I check on every node, or would that take too much time?

Definitely not every node.

You want to check often enough that your program is responsive to input, but as little as possible so you don't hurt the search. My program tries to poll 12 times per expected search time, i.e. if it expects to search 5M nodes, then I poll every 2^18-1 = 262143 nodes. I think it is also good to poll at least once every second or two, for responsiveness.

Re: Getting Engine to Communicate With WinBoard

PostPosted: 04 Sep 2010, 06:23
by beneficii
Thanks.

One other question. I'm reading this idiom:

time N
otim N
MOVE
Sent when the opponent makes a move and the engine is already playing the opposite color.


So if the opponent of the engine makes a move, these 3 commands are sent? Should my engine depend on these commands to help keep track of the time?

Re: Getting Engine to Communicate With WinBoard

PostPosted: 04 Sep 2010, 11:37
by H.G.Muller
It would be safer to have it keep track of the time itself, because the protocol does not offer the guarantee that these commands would always be sent. (I think all GUIs do it in practice, though.)

In any case, you should use them to sync your internal time keeping, as communication delays could easily cause a discrepancy, which might make you lose on time if not corrected.

Re: Getting Engine to Communicate With WinBoard

PostPosted: 04 Sep 2010, 18:09
by beneficii
Hmm, looking more closely, I see this feature:

time (boolean, default 1, recommended 1)
If time=1, xboard will send the "time" and "otim" commands to update the engine's clocks; if time=0, it will not.


That means it is actually documented, right? (Note: Since I am doing this engine for a chess variant, I have no plans to try to make it compatible with UCI.)

Re: Getting Engine to Communicate With WinBoard

PostPosted: 04 Sep 2010, 21:20
by H.G.Muller
Well, the document that describes the protocol is a strange mix between protocol specs and peculiarities of the implementation in XBoard. And even this phrase does not say when exactly they will be sent.

Perhaps I am being paranoic here. But you have to keep an eye on the progress of time while the engine is thinking anyway, to know when to stop, so it is virtually no work at all to subtract the search time which makes you decide to stop searching from the timeLeft variable, so I always do that in my engines.

Which variant are you doing?

Re: Getting Engine to Communicate With WinBoard

PostPosted: 05 Sep 2010, 04:51
by beneficii
Omega Chess, that commercial variant. I told them about having adapted WinBoard to play Omega Chess, but I never got a response. It interested me enough to try to make an engine to play it and see what happens.

Anyway, what about while the engine's opponent is thinking? Should the engine keep track of time then?

Re: Getting Engine to Communicate With WinBoard

PostPosted: 05 Sep 2010, 11:21
by H.G.Muller
That depends on if you are interested in how much time the opponent has on his clock. Most engines simply ignore the otim command.

How do you indicate the Wizzard squares? Do you use coordinates for a 12x12 board, so that a1 is a Wizzard square? (I guess it should be a0 then, based on the rule that counting starts at 0 on boards with more than 9 ranks.) WinBoard does not really implement boards with more than 10 ranks: the PGN parser does not understand double-digit numbers, and rank-number 10 is printed as ':'. Have you patched WinBoard to fix that? I would be very interested to have such a patch in the main line, so we can also implement variants like Big Chess.

The rule that counting starts at 0 only makes sens on a board with 10 ranks, I guess. With 11 ranks you would need double-digit numbers anyway, and you might as well use 10 and 11...

Re: Getting Engine to Communicate With WinBoard

PostPosted: 05 Sep 2010, 22:47
by beneficii
H.G.Muller wrote:That depends on if you are interested in how much time the opponent has on his clock. Most engines simply ignore the otim command.

How do you indicate the Wizzard squares? Do you use coordinates for a 12x12 board, so that a1 is a Wizzard square? (I guess it should be a0 then, based on the rule that counting starts at 0 on boards with more than 9 ranks.) WinBoard does not really implement boards with more than 10 ranks: the PGN parser does not understand double-digit numbers, and rank-number 10 is printed as ':'. Have you patched WinBoard to fix that? I would be very interested to have such a patch in the main line, so we can also implement variants like Big Chess.

The rule that counting starts at 0 only makes sens on a board with 10 ranks, I guess. With 11 ranks you would need double-digit numbers anyway, and you might as well use 10 and 11...


I do use a 12x12 board, but I use w# for the wizard squares. From white's perspective, it goes w1 or lower left, w2 for lower right, w3 for upper right (that's upper right not upper left), and w4 for upper left. The main 10x10 part goes simply from a to j and 0 to 9. For the squares in the 12x12 board that are not wizard squares or squares in the 10x10 board, I create a special 12x12 table in Winboard that marks squares as passable or impassable. I simply perform the calculations to produce and read the algebraic notation.

So I did not try to fix the problem with double-digit numbers, but simply got around it by implementing the wizard squares as specified on the Omega Chess website.

To brag, I also handled disambiguation better than the applet at the Omega Chess website. For example, if you have a queen at f9 and a queen at w3 (of the same color), where they can both move to f5, you need to disambiguate that in the notation. The Google applet for Omega Chess I find does not attempt disambiguation at all, whereas the applet at the Omega Chess website messes up if in disambiguation the piece moved from a wizard square. (You get some weird looking characters.) For a move from the wizard square, Winboard would mark it as "Qwf5", assuming that there is no queen on w1 that could also go there--in that case, Winboard would mark it as "Qw3f5".

EDIT: If you look at my first post on this forum, you can find the link to Winboard that implements Omega Chess, and the source.

EDIT 2: Regarding the clock, couldn't my engine be told to play its opponent, or would I be able to disable that through the feature command?

Re: Getting Engine to Communicate With WinBoard

PostPosted: 06 Sep 2010, 09:12
by H.G.Muller
It could be told to play its opponent, but in this case WB protocol specs very clearly state that it is the GUIs duty to tell the engine its new time in that case. If the GUI does not do that, the engine is supposed to continue using its own time, which it was using for the other side before. This is what "always stays with the engine" means in the specs of the 'time' command. This is actually essential for the way the protocol is used, where you want to send a time command before sending 'go', where 'go' changes the engine's idea of what side it is playing (or you would not have had to send it). So even before the 'go', 'time' must be used to send the engine the time for the side it will play after the 'go'.

I think that the concept of a 'blocked square', displayed as black, could be generally useful to have. Perhaps indicated in FEN as '#', to set up non-square boards.

I suppose you have used the #defined variables ONE and AAA used in converson of internal to external (text) coordinates to become dependent on if the variant is omega or not? It must be a real pain to make sure these Wizzard squares work in each of the move formats...