IntroductionCheckerBoard 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.
LimitationsThe 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 APICheckerBoard 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 FunctionsThe current CheckerBoard API (version 2) requires the following 2 functions:
int WINAPI getmove(int board, int color, double maxtime, char str, int *playnow, int info, int moreinfo, struct CBmove *move);
int WINAPI enginecommand(char command, char reply);
where struct CBmove is defined as follows:
If you plan to write an engine which plays English/American checkers, you can immediately forget about the
struct CBmove again.
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; // intermediate squares to jump to
struct coor del; // squares where men are removed
int delpiece; // piece type which is removed
The function getmove gets a move from the engine: getmove receives the current board position in b. 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
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.
#define WIN 1
#define LOSS 2
#define UNKNOWN 3
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:
- about: print a short description of your program in the reply string. This will be displayed in a message box, so you must also provide the formatting with \n for new lines.
- get ... asks for the value of an option:
- get protocolversion: print the protocol version number in reply (currently "2"). This enables the interface to detect older engines and interact properly with them if the protocol is updated.
- get gametype: print the game type number of the version of checkers your engine plays in the reply string. American/English: 21, Italian: 22, Spanish: 24, Russian: 25, Brazilian: 26.
- get book: print the book strength in the reply. Currently, CheckerBoard supports values 0...3, meaning no book, all kinds of moves, good moves, best moves, respectively. How you want to interpret the book strength is your decision.
- get hashsize: print the size of the hashtable in MB in reply.
- get dbmbytes: print the size of the endgame database cache in MB in reply.
- get allscores: print 1 if you are in all scores mode (the engine displays a list of all moves with their scores instead of the normal search info), 0 if you are in normal mode. The all scores mode is a good tool for a human to help in analysis.
- help: print the name of a HTML help file in reply. CheckerBoard will invoke the default HTML viewer to display the file.
- hint: print a hint in reply for novice players. Currently not supported by CheckerBoard.
- name: print the name of your engine in the reply string.
- set ... X sets an option to X.
- set book X: X = 0,1,2,3. meaning see above.
- set hashsize X: set the hashtable size to X MB.
- set dbmbytes X: set the endgame database cache to X MB.
- set allscores X: X = 0,1. meaning see above.
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 FunctionsIf 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, 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