Creating an engine tournament program

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

Dave_N
Posts: 153
Joined: Fri Sep 30, 2011 7:48 am

Creating an engine tournament program

Post by Dave_N »

I found that the uci engine protocol page has some information missing.

I have infinite analysis mode working with a reading thread that gets input every 100ms. So far so good. Multi-pv mode is working. To set the move each time I have to set the FEN string, not calling "ucinewgame" each time the position changes.
I don't understand how to change the number of pv's while analyzing, I think I have to use "ucinewgame" and then set the options, otherwise I don't see a change in the number of pv's even if I tell the engine to stop first.

For game playing there is no need to set the fen ... in fact after the first ucinewgame and the go command the position is set with

"position moves "

followed by the most recent move string in long algebra notation. Then the next go command can be issued to the engine whose move it is.
I didn't see this in the specification however creating a position from startpos and setting the entire list of moves is unintuitive. I am not sure about the how multi-pv mode is changed.
Dave_N
Posts: 153
Joined: Fri Sep 30, 2011 7:48 am

Re: Creating an engine tournament program

Post by Dave_N »

Fixed ...

I call "stop" then set the option then start again without problems, however I think its best to wait for "readyok" while I have simply called the commands without waiting or stopping the read thread. (this is of course simply for testing purposes, making sure the engine is ready to change states is the next task).

The above problem must have been a bug.
User avatar
ilari
Posts: 750
Joined: Mon Mar 27, 2006 7:45 pm
Location: Finland

Re: Creating an engine tournament program

Post by ilari »

Dave_N wrote:I have infinite analysis mode working with a reading thread that gets input every 100ms.
If you already have a separate thread for reading, why do you poll for input every 100 ms? It sounds like you could easily use blocking read calls and get all input practically immediately.
mcostalba
Posts: 2684
Joined: Sat Jun 14, 2008 9:17 pm

Re: Creating an engine tournament program

Post by mcostalba »

ilari wrote: If you already have a separate thread for reading, why do you poll for input every 100 ms? It sounds like you could easily use blocking read calls and get all input practically immediately.
I have thought about using a thread for async GUI events. Thread would block on std::getline() as you pointed out. My problem is that I don't know how to force the thread to wake up and unlock, for instance if I want the thread to exit.

Do you have some suggestions / code examples of how to do it ?
Dave_N
Posts: 153
Joined: Fri Sep 30, 2011 7:48 am

Re: Creating an engine tournament program

Post by Dave_N »

I am actually working on thread safety issues so the code isn't complete ... the biggest problem is the need to use the board processing code to calculate the pgn strings from the long algebra notation.
Dave_N
Posts: 153
Joined: Fri Sep 30, 2011 7:48 am

Re: Creating an engine tournament program

Post by Dave_N »

The reason for the 100ms time interval is for the bullet chess clock.

for thread safety during Kibitzing I envisage a variation board setup, when Kibitz is pressed the big board is accessed first and the current FEN string is copied and the variation board is set up. Then the read thread is started and it just reads stdin and processes moves on the variation board. When Stop Kibitzing is pressed the read thread is stopped. If the user makes a move while the engine is kibitzing the read thread is stopped and the "stop" command is issued to the engine, then when the move is complete the fen is copied into the variation board and the engine is sent the "position moves" message and "go infinite" then the thread is restarted . I don't see any need for a critical section or anything.
User avatar
ilari
Posts: 750
Joined: Mon Mar 27, 2006 7:45 pm
Location: Finland

Re: Creating an engine tournament program

Post by ilari »

mcostalba wrote:I have thought about using a thread for async GUI events. Thread would block on std::getline() as you pointed out. My problem is that I don't know how to force the thread to wake up and unlock, for instance if I want the thread to exit.

Do you have some suggestions / code examples of how to do it ?
Of course you can just kill the thread (eg. by using the TerminateThread() function in WINAPI), but that's an extreme measure that's usually not recommended.

Cute Chess has the EngineProcess and PipeReader classes for Windows, but there I use pipes and ReadFile() instead of std::getline(). I don't know what exactly needs to be done with std::getline(), but with pipes and ReadFile() the main requirements are:

- After creating the child process, the child process' ends of the read and write pipes should be closed (ie. first you have 4 pipes, then you close 2). Otherwise ReadFile and WriteFile may not terminate when the child process does.
- The child process should be terminated before deleting the reader thread.
- If ReadFile() raises ERROR_INVALID_HANDLE or ERROR_BROKEN_PIPE, you're probably doing it wrong.
User avatar
hgm
Posts: 27808
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: Creating an engine tournament program

Post by hgm »

Dave_N wrote:The reason for the 100ms time interval is for the bullet chess clock.
I don't get it. How does using a slow method help for the bullet chess clock? Seems to me it would be important there to not waste 100ms...
Dave_N wrote:I am actually working on thread safety issues so the code isn't complete ... the biggest problem is the need to use the board processing code to calculate the pgn strings from the long algebra notation.
In WinBoard, the thread safety comes from forbidding recursive events. So if the thread waiting for engine input wakes up because the engine sent some thing, and it hapens to be a PV, it can safely access the game that is in storage to convert the PV to SAN, as long as it restores everything to the original state before it is done. What I do in practice is shelve the tailof the game on the variation stack, (if the engine was not thinking on the final position of the stored game), and then process the PV like any input moves from the engine to append them to the truncated game.

Same with the variation board; when the user requests it, the PV he selected for display will be appended to the stored game (possibly replacing the game tail), so the user can step through it using the normal display routines, and the game tail is restored when he switches back from variation board to the game board. Other events, such as an incoming move from the engine, also force that switch, by restoring the shelved game, and displaying that.
Dave_N
Posts: 153
Joined: Fri Sep 30, 2011 7:48 am

Re: Creating an engine tournament program

Post by Dave_N »

hgm wrote:
Dave_N wrote:The reason for the 100ms time interval is for the bullet chess clock.
I don't get it. How does using a slow method help for the bullet chess clock? Seems to me it would be important there to not waste 100ms...
Dave_N wrote:I am actually working on thread safety issues so the code isn't complete ... the biggest problem is the need to use the board processing code to calculate the pgn strings from the long algebra notation.
In WinBoard, the thread safety comes from forbidding recursive events. So if the thread waiting for engine input wakes up because the engine sent some thing, and it hapens to be a PV, it can safely access the game that is in storage to convert the PV to SAN, as long as it restores everything to the original state before it is done. What I do in practice is shelve the tailof the game on the variation stack, (if the engine was not thinking on the final position of the stored game), and then process the PV like any input moves from the engine to append them to the truncated game.

Same with the variation board; when the user requests it, the PV he selected for display will be appended to the stored game (possibly replacing the game tail), so the user can step through it using the normal display routines, and the game tail is restored when he switches back from variation board to the game board. Other events, such as an incoming move from the engine, also force that switch, by restoring the shelved game, and displaying that.
I have something similar at the moment, however I intend to use a second board later, the main board calls Fen() and this is sent to the engine when the analyze button is pressed, then the read thread checks stdin every 100ms with

Code: Select all

while( input.CanRead() ){...}
and this shouldn't read the input that has already been processed. Basically I doubt the code that parses input and sets the board positions is very slow (~<1ms) however I should profile the whole thing at some stage.

The main difference is that I don't actually create nodes for the moves, however I was considering inserting the moves as a special type of variation to make copying the analysis to the notation easier.