Jan 9, 2007

[Guide] Communication Protocols

I have already touched this subject a few times. Here is a more thorough explanation.

What it does

Chess communication protocols are used to help chess engines communicate with an interface.

The protocol sends information about the game on a certain form, and receives moves and information from the engines based on given standards.

The main advantage is of course that you only need one interface to run several different engines. As long as they support the protocol used you will be able to run them.

The two main protocols

There are two main chess communication protocols. WinBoard and UCI.

WinBoard (or xboard, they are the same) was developed by Tim Mann and is probably the most common protocol, in recent years however the UCI protcol developed by Rudolf Huber and Stefan Meyer-Kahlen (creator of the Shredder engine), has gained ground.

The specifications can be found here:

UCI specifications
WinBoard specifications

How they work

The main principle is the same for both protocols. The interface (be it winboard or uci compatible) sends strings with information, and handles responses from the engine.

To be able to catch the information sent from the interface you need a loop that looks for input. In Java it could look like this:
BufferedReader reader =
new BufferedReader(new InputStreamReader(System.in));
for(;;) // Endless loop
String command = reader.readLine();

This should be familiar to anyone who has ever written a Java program that accepts input.

Sending information to the interface is done with the System.out.print command.

The format of the input and output is specified in the specifications of the protocol used.

For example when the user (could be a player or another engine) makes a move, WinBoard will send the string:
"usermove e2e4"
When the engine receives this input it should make it on the board and start thinking, and then send a response like this:
System.out.println("move e2e4");
This tells the interface that the engine want to make the move.

Using UCI it works a bit differently. When the user makes a move a string on this form is sent:
"position startpos moves e2e4 e7e5 g1f3"
"position fen [a fen string] moves e7e5 g1f3"
The 'startpos' indicates the game started from the initial position, and the moves following 'moves' are the moves played since the startposition. If it is a fen-string instead it indicates that the game probably started from some other position.

When the engine receives this line it should setup the position (be it start position or the fen-string) and play the moves on the internal board.

The 'position' string from UCI does not tell the engine to start thinking or responding. This is done with the 'go' command. So when the engine receives 'go' it should start thinking on the position currently on the board, which in a normal game will have been received in a 'position'-string right before the 'go'.

And then send its move using:
System.out.println("bestmove e2e4");
There is a 'go' command in WinBoard as well, but this is only sent to make the engine leave 'force' mode after setting up the board, or if we want the engine to play white from the initial position.

If the engine is told to go to 'force' mode by WinBoard it should register moves on the board, but not respond or think.

And much more

There are a number of other commands both for WinBoard and UCI, but I leave that to you to read about in the specifications.

I urge you to read the specifications carefully. Make sure your engine does exactly what they say, since the interfaces will assume it does and weird things can happen if you try to do it differently.

Which to choose

As you can see there are subtle differences in the two protocols. Which protocol to use is a matter of taste. You have to consider what interfaces you will be using and decide which one suites you the best.

A tip is to choose one protocol and stick with it. Maintaining both is twice the work, not only do you have to be able to handle different inputs, but you also have to send thinking lines and moves in two different ways.

On the other hand your engine will run on pretty much any interface if it supports both.

No comments: