-
Notifications
You must be signed in to change notification settings - Fork 8
ChenServer
ChenServer is a version of the Chenard chess engine that enables programmers to add chess functionality to any client software that can communicate using a TCP socket. It is designed for simplicity, consistency, and ease of implementation for developers who want to write a chess-related program. ChenServer knows everything about the rules of chess, and even how to play chess, so your program doesn't need to!
ChenServer is written in C++ and runs on Windows, Linux, or Mac OS X. The client software may use ChenServer by sending an HTTP GET request, or via a terse TCP command terminated by a single newline character. The protocol is fully documented here.
Table of Contents
- Building the code
- Running ChenServer
- Demo #1: using the
-s
option - Demo #2: running ChenServer using TCP
- Demo #3: Using ChenServer with HTTP GET requests
- TCP client implementation details
- Complete command reference
To build ChenServer, first clone the Chenard repository from Github. Make note of the directory where you cloned it, then follow the instructions below based on your operating system:
-
Windows: Use Visual Studio 2013 to open the solution file
chenard.sln
. For best performance, choose Build / Configuration Manager, select Release from the "Active solution configuration" pulldown, then Close. Chose Build / Rebuild Solution. When you are finished, there will be a directory calledRelease
inside the directory where you cloned the Chenard repository. It will contain the executablechenserver.exe
. It is a good idea to copychenserver.exe
to some other directory where you can run it. -
Linux or Mac OS X: You will need a fairly recent version of
g++
that supports C++11. Usecd
to change into the directory where you cloned the Chenard Git repository and use thebuild
script under thechenserver
andchenclient
directories. Executables (also calledchenserver
andchenclient
) will be created in the respective directories. Example:
sudo apt-get install build-essential g++ # if needed
cd chenserver
./build
cd ../chenclient
./build
There are two different ways to run ChenServer based on the command line parameters you give it.
The -s
option reads all commands from standard input and writes all responses to standard output:
chenserver -s
The -p
option communicates over the specified TCP port. The <port>
must be a valid port number in the range 1..65535.
chenserver -p <port>
Try opening a command prompt and running chenserver -s
. You will see the program just sit there with a command prompt. Enter the command new
, followed by the command status
. You will see this:
C:\test>chenserver -s new OK status * rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1
The new
command makes sure you are starting with a fresh chess game. The status
command shows an asterisk *
(which means the game is in progress) followed by the current state of the chess board in Forsyth–Edwards Notation (FEN).
I have created a FEN display tool to help you visualize chess positions expressed as FEN.
You (or a program you write) can ask ChenServer for a list of all legal chess moves using the legal
command:
legal OK 20 b1c3 b1a3 g1h3 g1f3 a2a3 a2a4 b2b3 b2b4 c2c3 c2c4 d2d3 d2d4 e2e3 e2e4 f2f3 f2f4 g2g3 g2g4 h2h3 h2h4
To make a move on the chess board, use the move
command:
move e2e4 OK 1 status * rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1
You can ask the Chenard AI to decide on a move using the think
command following by the maximum number of milliseconds it should spend thinking.
think 1000 OK e7e5 e5 status * rnbqkbnr/pppp1ppp/8/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq e6 0 2
For the convenience of your program, ChenServer's response to the think
command includes both simple algebraic notation and Portable Game Notation (PGN). Both formats are available for every command in ChenServer. For example, you can make the next move for White using either move b1c3
or move Nc3
— both mean the same thing. See the complete command reference for more details.
For now, you can use the exit
command to quit out of ChenServer:
exit OK C:\test>
When you built the solution chenard.sln
, in addition to chenserver.exe
, it also created a sample client program called chenclient.exe
. This demo will require you to open up two command prompt windows at the same time. It will be helpful to move and re-size the two command prompt windows so that they do not overlap.
In the first window, enter the following command.
C:\test>chenserver -p 1234
Windows Firewall may pop up a box like the one shown below telling you that the program is trying to access a port. If so, click the "Allow access" button.
You may need to adjust the port number 1234
if something is already using it on your machine.
Now switch to the second command prompt window and enter the following commands:
C:\test>chenclient localhost 1234 "status" * rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1 C:\test>chenclient localhost 1234 "move e4" OK 1 C:\test>
In both cases, chenclient.exe
program sends the command to chenserver.exe
, receives the response, prints it to the screen, and exits. Meanwhile, the chenserver.exe
program will keep running. You can try other commands from Demo #1.
You must use quotes around the command if it contains any spaces, as in the example here with move e4
.
The chenserver.exe
program will also respond to simple HTTP GET requests on the same port, with some limitations. This may be helpful for some programming languages in which it is easier to send HTTP GET requests than to perform low-level TCP port I/O. While chenserver -p 1234
is running, try opening the following link in your web browser.
http://localhost:1234/status
Then try making a move:
http://localhost:1234/move+e4
Notice that in a URL, you have to escape each space character as a +
.
The sample client source file main.cpp
illustrates the details of how a client program can communicate with ChenServer using TCP. Here are the main points to understand:
- The client opens a TCP socket to ChenServer for each command it wants to send.
- The client writes the command to the socket as plain ASCII text followed by a single newline character (
'\n'
or0x0d
or character 13, however you want to think of it). The newline is crucial so that ChenServer knows the command is complete. Without it, both the server and your client program will get stuck! - The client then waits for a response. The response will also be an ASCII string terminated by a newline character.
- As soon as the client reads the newline character, it closes the socket. The transaction is now complete.
This sequence of steps is repeated for every command.
Here is the complete reference for the commands supported by ChenServer, along with the responses (including both success and failure cases).
Causes the server to exit.
Example:
exit OK C:\test>
Displays the history of all the moves in the current game, using either PGN (Portable Game Notation) or algebraic notation. The default format is algebraic. If successful, the output is the word OK
followed by a space, then the decimal number of moves in the history, followed by the space-delimited moves themselves.
Example:
new OK history OK 0 move e4 e5 Nc3 Nf6 OK 4 history OK 4 e2e4 e7e5 b1c3 g8f6 history pgn OK 4 e4 e5 Nc3 Nf6 history alg OK 4 e2e4 e7e5 b1c3 g8f6 history tuna BAD_FORMAT
The last example shows what happens if you provide an invalid format specifier. Your program should interpret anything other than OK
at the front of the response as indicator than an error occurred.
The output looks similar to that of history
, but this command shows a list of all legal moves for the current player. The output consists of the word OK
followed by a space, followed by the decimal number of legal moves, followed by the space delimited moves themselves. The option pgn
selects Portable Game Notation format, and alg
selects algebraic format. The default is algebraic.
If there are no legal moves (for example, a player has been checkmated) the output will be OK 0
.
Example:
new OK legal OK 20 b1c3 b1a3 g1h3 g1f3 a2a3 a2a4 b2b3 b2b4 c2c3 c2c4 d2d3 d2d4 e2e3 e2e4 f2f3 f2f4 g2g3 g2g4 h2h3 h2h4 legal pgn OK 20 Nc3 Na3 Nh3 Nf3 a3 a4 b3 b4 c3 c4 d3 d4 e3 e4 f3 f4 g3 g4 h3 h4 legal alg OK 20 b1c3 b1a3 g1h3 g1f3 a2a3 a2a4 b2b3 b2b4 c2c3 c2c4 d2d3 d2d4 e2e3 e2e4 f2f3 f2f4 g2g3 g2g4 h2h3 h2h4
Makes zero or moves on the chess board. Each move may be specified in either PGN or algebraic notation (automatically detected).
This command guarantees an "all or nothing" approach. If any move in the sequence is illegal or invalid, an error message will be printed and the board will not be changed: the board will remain in the same state it was before the move
command was received. If the entire sequence of moves is legal, all the moves are made in the specified order on the board. In this case the output will be the word OK
, then a space, followed by the number of moves that were made as a decimal number.
To castle king-side, you can either algebraically indicate the king moving two squares toward the rook (e1g1
for White, e8g8
for Black) or you can use PGN notation O-O
(capital letter O, not zero).
To castle queen-side, use algebraic notation (e1c1
for White, e8c8
for Black) or the PGN notation O-O-O
.
To promote a pawn using algebraic notation, use the source and destination square followed by one of the following four letters to indicate which piece to promote it to:
-
q
for queen -
r
for rook -
b
for bishop -
n
for knight
For example, e7e8q
will move a pawn from e7 to e8 and promote it to a queen. The equivalent PGN notation for this move is e8=Q
.
To capture en passant using algebraic notation, just indicate the source and destination squares of the capturing pawn. For example, if Black has just moved a pawn two squares from d7 to d5, and White has a pawn at e5, White may capture Black's pawn by playing e5d4
(algebraic) or exd4
(PGN). In either format, ChenServer understands that the Black pawn at d5 is to be removed from the board, even though the target square is d4.
When using PGN to submit a move that causes check, the suffix +
is optional. Likewise, #
is optional for any move that causes checkmate. The move will be recognized and accepted with or without these suffixes.
Example:
new OK move e4 OK 1 status * rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1 move g8f6 Nc3 OK 2 status * rnbqkb1r/pppppppp/5n2/8/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq - 2 2 move Nc6 Bb2 BAD_MOVE Bb2 status * rnbqkb1r/pppppppp/5n2/8/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq - 2 2
Starts a new game. The chess board is set to its initial configuration and any move history is erased. The command outputs the line OK
.
Example:
new OK
Displays the current game status, followed by a space, followed by the game position expressed in Forsyth–Edwards Notation (FEN). I have created a FEN display tool to help you visualize chess positions expressed as FEN.
The game status is one of the following codes. (Note that these are the same codes used in a [Result]
tag in a PGN file.)
-
*
The game is still in progress (the game is not over). -
1-0
White has won the game. -
0-1
Black has won the game. -
1/2-1/2
The game has ended in a draw.
A draw may occur by stalemate, threefold repetition, the 50-move rule, or when neither side has sufficient material to deliver a checkmate. If the client software wishes to implement draw by agreement, it may do so in its user interface, but there is no need for ChenServer to be involved.
Likewise, ChenServer has no concept of a player resigning. Client software may implement that in its user interface without involving ChenServer in any way.
Example (note the contrived checkmate):
new OK move e4 f6 Nc3 g5 OK 4 status * rnbqkbnr/ppppp2p/5p2/6p1/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq g6 0 3 move Qh5 OK 1 status 1-0 rnbqkbnr/ppppp2p/5p2/6pQ/4P3/2N5/PPPP1PPP/R1B1KBNR b KQkq - 1 3
Tests the given move m (expressed in either PGN or algebraic format) for legality. This command never changes the state of the game in any way.
If m is a legal move, the output is of the form OK
, followed by a space, then m expressed in algebraic notation, then another space, then m expressed in PGN. Thus the test
command can be used by client software to convert move notation from one form to another.
If the move is illegal, the output is the single word ILLEGAL
.
Example:
new OK test Nc3 OK b1c3 Nc3 test b1c3 OK b1c3 Nc3 test a1b1 ILLEGAL
Uses the Chenard AI to choose and play a move in the current board position. This is one of the most important commands if you want your client software to allow people to play against a computer opponent.
The millis argument is an integer number of milliseconds in the range 1..300000 (which is the range from 0.001 seconds to 5 minutes) that specifies the maximum amount of time the AI is allowed to think. In some cases the response will be almost instant regardless of the time specification. For example, the AI may know an opening move or it may see a forced checkmate and thus not need to think a long time. A good value will be somewhere between 1000 to 5000 for a challenging game without having to wait too long on each turn.
Your client program has total freedom of when and whether to use the think
command. It must manage whether it wants the computer to play White, Black, neither, or both. Your client program may change its mind at any time simply by choosing to use the think
command or not at any time. ChenServer has no concept of White or Black "belonging" to either a human opponent or the computer; it simply does whatever it is told by the client program each time it is given a command.
If the Chenard AI can find a legal move, it will choose the move it thinks is best and print OK
followed by a space, followed by the move in algebraic notation, then another space, then the same move expressed in PGN.
If there are no legal moves available (the game is over), the output will be GAME_OVER
.
The think
command will never resign, nor will it ever offer a draw. It will always choose a move and make it on the board if possible.
Example:
new OK move e4 f6 Nc3 g5 OK 4 think 1000 OK d1h5 Qh5# think 1000 GAME_OVER
Reverses the last n turns on the chess board, where n is an integer from 1 to the number of turns that have been played. (I say turns because move usually means a pair of turns in chess.) You can use this option to allow a human player to take back an action he regrets.
If the value of n is not an integer, or it is outside the allowed range of values, the response message is BAD_NUM_TURNS
. In this case the board is left unchanged.
Otherwise, the last n turns are rolled back and the response text is OK
.
Example:
new OK move d4 d5 c4 OK 3 history OK 3 d2d4 d7d5 c2c4 undo 1 OK history OK 2 d2d4 d7d5 undo 2 OK history OK 0 undo 1 BAD_NUM_TURNS