Skip to content

ChenServer

Don Cross edited this page Jun 30, 2015 · 56 revisions

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

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 called Release inside the directory where you cloned the Chenard repository. It will contain the executable chenserver.exe. It is a good idea to copy chenserver.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. Use cd to change into the directory where you cloned the Chenard Git repository and use the build script under the chenserver and chenclient directories. Executables (also called chenserver and chenclient) will be created in the respective directories. Example:

    sudo apt-get install build-essential g++   # if needed
    cd chenserver
    ./build
    cd ../chenclient
    ./build

Running ChenServer

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>

Demo #1: using the -s option

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>

Demo #2: running ChenServer using TCP

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.

Windows Firewall

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.

Demo #3: Using ChenServer with HTTP GET requests

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 +.

TCP client implementation details

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' or 0x0d 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.

Complete command reference

Here is the complete reference for the commands supported by ChenServer, along with the responses (including both success and failure cases).


exit

Causes the server to exit.

Example:

    exit
    OK

    C:\test>

history [pgn | alg]

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.


legal [pgn | alg]

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

move [m1 m2 m3 ...]

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

new

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

status

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

test m

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

think millis

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

undo n

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