UCI Chess Engine Protocol

I really like the UCI protocol.  I know there are diehard fans of Winboard out there, but for me I like the cleanness of UCI.  One of the aim I have for Maverick is to support as much of the protocol as possible.  In Monarch the UCI code was stable but it was a bit messy.  So I put some thought into how I could simplify the implementation.  Here’s what I came up with for Maverick:

There are two threads.  The first thread just listens for user / GUI input.  We’ll call this the listening thread. The second thread runs the engine’s search and reports back with it’s findings.  We’ll call this the thinking thread.  Most, if not all, problems with this type of implementation crop up when one thread gets out of sync with the other thread’s state. This usually results in the thinking thread being sent unexpected commands which are either ignored or processed incorrectly.

The insight I had was by using the UCI protocol there are only two commands which change the state of the thinking thread.  These are “go” and “stop”, (there is also “quit”, which I handle as a special form of “stop”).  So the “go” command needs to change the state of the thinking thread from “waiting” to “thinking”.  And the stop command needs to change the state back from “thinking” to “waiting”.  In Maverick’s implementation I’ve also added “Start_Thinking” as another state for the thinking thread.  This is needed when there is rapid fire changes and the GUI is blasting commands at the engine.  Under the rapid fire scenario the engine can receive a stop command before the engine starts to think.  By having the “Start_Thinking” state the engine can wait for the search to start before taking any more input from the GUI.

Here’s the code:

void uci_stop()
{
uci.stop = TRUE;
while (uci.engine_state != UCI_ENGINE_WAITING)
Sleep(1);
}

void uci_go(char *s)
{
search_start_time = time_now();
last_display_update = search_start_time;
set_uci_level(s, position->to_move);
uci.engine_state = UCI_ENGINE_START_THINKING;
while (uci.engine_state == UCI_ENGINE_START_THINKING)
Sleep(1);
}

It seems to work well and be rock-solid stable!

Maverick is almost ready to start playing chess.  A few more clean-ups needed!