CB API reference

Introduction

CheckerBoard 1.64 adds an "engines" directory to the CheckerBoard directory. Your engine should be installed into that directory, and supporting files should also go there (helpfiles etc). Your program will see the CheckerBoard directory as working directory when it is called from CheckerBoard.

I made some minor changes to this document on April 24, 2005. They are in blue throughout, so that those who want to see what changed can do so efficiently.
CheckerBoard is explicitly only designed as an interface to checkers engines, and CheckerBoard is free. Therefore, CheckerBoard is a good choice for an interface if you want to develop a checkers engine, because it relieves you from the hassle of interface programming, and because it gives you the capability to test your engine against other engines with the engine-engine mode. If you would like to program an engine for CheckerBoard or if you have already written a checkers program and want to adapt it to run as engine in CheckerBoard, here is the documentation of the CheckerBoad API. The CheckerBoard API is currently the only standard communication protocol for checkers engines and interfaces, and is also supported by the commercial program Sage, and hopefully, in the future also by further checkers programs. If you want to use my engine Cake in your checkers program, you are welcome to do so. There are no restrictions on the use of cake.dll by third parties - you may also use it in a commercial program. Of course, cake.dll comes without any warranties, all liabilities are excluded.

Limitations

The CheckerBoard API is not a well-designed protocol by a professional computer programmer. I know that it is far from perfect, and if you feel you have a suggestion for an improvement, feel free to tell me about it. A big hole in the protocol is that pondering is not supported. Besides that, there is a number of minor limitations which I do not think are very important. However, if you think otherwise, please tell me about it.

The CheckerBoard API

CheckerBoard expects your engine to be compiled as a dll and to be in the working directory of checkerboard.exe - or in the path. An engine must support 2 required functions. If your engine plays a different version than English checkers, you must provide 2 more functions for multi-version support. The calling convention for all functions is __stdcall().

Required Functions

The current CheckerBoard API (version 2) requires the following 2 functions:

int WINAPI getmove(int board[8][8], int color, double maxtime, char str[1024], int *playnow, int info, int moreinfo, struct CBmove *move);
int WINAPI enginecommand(char command[256], char reply[1024]);

where struct CBmove is defined as follows:

struct CBmove
{
int jumps; // number of jumps in this move
int newpiece; // moving piece after jump
int oldpiece; // moving piece before jump
struct coor from,to; // from,to squares of moving piece
struct coor path[12]; // intermediate squares to jump to
struct coor del[12]; // squares where men are removed
int delpiece[12]; // piece type which is removed
}

struct coor
{
int x;
int y;
}
If you plan to write an engine which plays English/American checkers, you can immediately forget about the struct CBmove again.

The function getmove gets a move from the engine: getmove receives the current board position in b[8][8]. The side to move is in color, and maxtime is the time your program should think on average for its move. CheckerBoard does not check the time usage of an engine, which means you can take as much time as you like on your move if you want - but of course that's not what the user expects! The board position and the side to move use the conventions:

#define WHITE 1
#define BLACK 2
#define MAN 4
#define KING 8
#define FREE 0

so for instance if an array entry is 10 that means it is a black king. You can use statements like if b[i][j]==BLACK|KING... to find out if there is a certain piece on a square.
The parameter color is either BLACK or WHITE and tells the engine which side is to move.
The next parameter is a pointer to a string. This string is displayed in the status bar of CheckerBoard. You can use this to display search information. Just write something like sprintf(str,"i am winning"); and "i am winning" will be displayed in the status bar. The status bar is updated every 0.1s in CheckerBoard. There is no defined format for the string you should display there, you are completely free. However, I suggest that you do something similar as Cake does.
The next parameter is a pointer to the integer playnow. You should monitor playnow and immediately return if it is nonzero. This means that the user has chosen "Play" in the CheckerBoard menu.
The next parameter, info, is a bunch of flags which are used for some advanced stuff:
Bit 0 is set if the 'natural course' of the game has been interrupted, for instance with a take back or new game command. you can use this parameter to check if the position is repeating itself; as long as this bit is not set, you are playing a normal game and can check for repetitions (and avoid them if you want). As soon as it is set, you must reset your repetition detection.
Bit 1 is set if 'exact' has been selected in the 'level' menu. In this case, your engine should return a move exactly after the time that has been selected by maxtime, and not take any longer.
Bit 2 is set if an incremental time level is being used. In this case, the increment per move is passed to the engine in the parameter "moreinfo". Currently this is unused by CheckerBoard.
Bit 3 is set if the parameter maxtime is meant to be interpreted as a search depth. Also unused as of now.
The further bits are reserved for future extensions.
The parameter moreinfo is currently unused and also meant for further extensions. It is supposed to hold additional information to a set bit in the info parameter.
Getmove should return a value between 0 and 3, defined as follows:
#define DRAW 0
#define WIN 1
#define LOSS 2
#define UNKNOWN 3
CheckerBoard uses the return value in automated engine matches to terminate a game when an engine claims a draw, win or loss. When CheckerBoard is in any other play mode, the return value of getmove is not used.

The enginecommand function is used for all other communication between engine and CheckerBoard. The interface uses enginecommand to send a command string to the engine, which should print a reply into the reply string. Here's a list of the commands your engine should support:

Your engine may choose not to implement some of the commands of the protocol. If your enginecommand does not handle a command issued to it by CheckerBoard, it should return 0 and print a question mark into reply. If you print the question mark on unhandled commands, CheckerBoard will gray out the corresponding options in the engine options dialog. Note that the 0 and the question mark are not synonyms: your engine may return a 0 if it is asked to use a huge hashtable, meaning that it did not change the hashtable size. As a general rule, you should print some acknowledgment in reply that you did handle a command. This is useful if you ever want to use the engine command dialog, which displays the reply of the engine. If it handles the command, it should return 1 to let CheckerBoard know that it understood and processed the command.
If you want to communicate with the user on the execution of a set command, you should not do so directly (e.g. by invoking MessageBox from your engine). Instead, print the following into the reply string:
"Message message-text" e.g. "Message Out of memory error, cannot allocate 1024 MB for hashtable"
CheckerBoard will recognize the keyword Message and display a message box with the message text. This addition gives interface programmers more flexibility how they might want to display engine messages. Note: the current version of CheckerBoard (1.621) does not support this yet, but the next version will.

Multi-Version Support Functions

If you want to write an engine which plays a different version of checkers than English, must add another function to your dll:
int WINAPI islegal(int board[8][8], int color, int from, int to, struct CBmove *move);

In addition to this, your engine command function must recognize the command get gametype and return the appropriate number for your version of checkers.
Islegal tells CheckerBoard about the rules of your version of checkers. When the user wants to play a move from 'from' to 'to', islegal is called. You must use your move generator to find out if 'color' can play this move on 'board'. If yes, return 1, else 0. If the move is legal, you must also tell CheckerBoard what it is, so that it can animate the move properly. You do this by filling in the CBmove struct.

In case that this is not clear enough, study the code of simple checkers, which is included in the CheckerBoard installation. Simple Checkers is an example for an English engine. If you plan to play a different version, look at the source code for dama to see how this works.

Once you have finished your engine, you must copy the dll into the CheckerBoard folder and select your engine with 'engine->select...'. Of course I would love to hear from you if you do write an engine for CheckerBoard. If you do, please send me a mail to nospam1 at fierz dot ch. I would like to link to your page, or, if you don't have one, I would put your engine on my server.

-- December 3, 2005