Usage
How to run FollyChess and connect it to a chess GUI.
Once you have compiled the engine, you can use it through a chess GUI or directly on the command line.
Using with a chess GUI #
FollyChess implements the Universal Chess Interface (UCI). It does not draw a board itself; a chess GUI does that and talks to the engine for you. Some GUIs that work well:
In your GUI, add a new engine and select the
bazel-bin/cli/follychess binary when prompted.
Running on the command line #
You can also talk to the engine directly via your shell. This is useful for debugging and scripting:
bazel-bin/cli/follychess
The engine then waits for commands. FollyChess supports a subset of the UCI protocol, described below. In the examples, commands you type are shown in bold; the rest is engine output.
uci #
Starts the UCI protocol. The engine identifies itself and lists its options.
isready #
Synchronizes with the engine. FollyChess answers readyok
once it has finished its internal setup.
d #
A custom command (not part of UCI). Prints the current position:
d
8: r n b q k b n r
7: p p p p p p p p
6: . . . . . . . .
5: . . . . . . . .
4: . . . . . . . .
3: . . . . . . . .
2: P P P P P P P P
1: R N B Q K B N R
a b c d e f g h
w KQkq - 0 1
position #
Sets up the board. It supports these forms:
Starting position. position startpos resets the
board to the starting position.
FEN string. position fen <fenstring> sets
the board to a position given in
Forsyth–Edwards
Notation:
position fen 8/2p5/3p4/KP5r/1R3p1k/8/4P1P1/8 w - - 0 1
d
8: . . . . . . . .
7: . . p . . . . .
6: . . . p . . . .
5: K P . . . . . r
4: . R . . . p . k
3: . . . . . . . .
2: . . . . P . P .
1: . . . . . . . .
a b c d e f g h
w - - 0 1
Adding moves.
position [startpos | fen <fenstring>] moves <move1> <move2> ...
applies a sequence of moves to the given position:
position startpos moves e2e4 e7e5 g1f3
d
8: r n b q k b n r
7: p p p p . p p p
6: . . . . . . . .
5: . . . . p . . .
4: . . . . P . . .
3: . . . . . N . .
2: P P P P . P P P
1: R N B Q K B . R
a b c d e f g h
b KQkq - 3 2
Moves use long algebraic notation:
| Type | Format | Example |
|---|---|---|
| Standard | <from><to> |
e2e4, g1f3 |
| Castling | <from><to> |
e1g1 (white kingside), e8c8 (black queenside) |
| Promotion | <from><to><piece> |
a7a8q (queen), h2h1n (knight) |
go #
Calculates the best move for the current position. The search can be limited in three ways:
Depth. go depth <plies> searches to a fixed
depth. The engine reports each completed iteration and finishes with the
best move it found:
go depth 3
info depth 1 score cp 69 nodes 41 nps 408 tthits 0 tthitrate 0.00 pv e2e4
info depth 2 score cp 0 nodes 182 nps 1799 tthits 0 tthitrate 0.00 pv e2e4 e7e5
info depth 3 score cp 41 nodes 908 nps 8715 tthits 1 tthitrate 0.00 pv d2d4 d7d5 c1f4
bestmove d2d4
Time. go movetime <milliseconds> searches
for a fixed amount of time, going as deep as the budget allows. When the
time runs out, the engine plays the best move from the last iteration it
completed:
go movetime 1000
info depth 1 score cp 69 nodes 41 nps 451 tthits 0 tthitrate 0.00 pv e2e4
...
info depth 6 score cp 5 nodes 75501 nps 116195 tthits 2133 tthitrate 0.04 pv d2d4 d7d5 e2e4 d5e4 f1b5 c8d7
bestmove d2d4
Nodes. go nodes <count> stops the search
once roughly that many positions have been visited. Unlike a time limit,
a node limit produces the same result on every run and on any machine,
which makes it useful for testing:
go nodes 20000
info depth 1 score cp 69 nodes 41 nps 451 tthits 0 tthitrate 0.00 pv e2e4
...
info depth 5 score cp 34 nodes 11217 nps 75929 tthits 417 tthitrate 0.05 pv d2d4 d7d5 c1f4 c8f5 b1d2
bestmove d2d4
The limits can be combined, in which case the search stops at
whichever limit is reached first. With no arguments, go
searches to a default depth of 6. Regardless of the limits, the engine
always completes at least a depth-1 search so that it can produce a
move.
bench #
A custom command (not part of UCI). Searches a fixed suite of 46
positions at a fixed depth (6 by default, or bench
<depth>). The suite spans the opening, sharp and quiet
middlegames, endgames, and terminal positions. Each position's regular
search output goes to standard output, while the position headers and
the summary go to standard error, so that standard output carries
nothing but engine protocol output:
bench
Position: 1/46 (rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1)
info depth 1 score cp 69 nodes 41 nps 2182 tthits 0 tthitrate 0.00 pv e2e4
...
info depth 6 score cp 5 nodes 75410 nps 1487441 tthits 2135 tthitrate 0.04 pv d2d4 d7d5 e2e4 d5e4 f1b5 c8d7
bestmove d2d4
Position: 2/46 (r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq - 0 10)
...
===========================
Total time (ms) : 5259
Nodes searched : 14539344
Nodes/second : 2764353
The Nodes searched count is deterministic: the same
source code produces the same count on every run and on any machine.
This makes it a signature of the search. A refactor that is not meant
to change search behavior must leave the count unchanged, while a
change to pruning or move ordering shows up as a different count.
Nodes/second tracks raw search speed.
quit #
Ends the engine process.