Toad is a work-in-progress chess engine, and serves as my personal excuse to write fun code in Rust.
It was originally built upon my chessie
crate, which is a chess library that handles board representation, move generation and all other rules of chess.
Development progress is recorded automatically in the changelog.
All progression/non-regression testing is done through OpenBench instance hosted here.
Strength of the latest version can be found on the CCRL pages- just search for Toad
!
Up for a game? Play against Toad on Lichess!
Being a chess engine, Toad is CLI application that, by default, will await commands via stdin
.
Toad does not have a GUI.
There are some commands you can use to view the board state and make moves, but Toad's primary use case is to be paired with a GUI or match runner like en croissant or cutechess.
For convenience, you can run any of Toad's commands on startup and Toad will exit immediately after that command's execution.
To run multiple commands on startup, pass them in with the -c "<command>"
flag.
You can pass in the --no-exit
flag to continue execution after the command(s) have finished executing.
Run the engine and execute the help
command to see a list of available commands, and --help
to view all CLI flags and arguments.
Toad abides (mostly) by the Universal Chess Interface protocol, and communicates through stdin
and stdout
.
The parsing of UCI commands and responses is handled by my uci-parser
crate.
The following UCI commands (and arguments) are supported:
uci
debug [ on | off ]
isready
setoption name <x> [value <y>]
ucinewgame
position [fen <fenstring> | startpos] [moves <move_1> ... <move_i>]
- Extended to include
position kiwipete
.
- Extended to include
go wtime <x> btime <x> winc <x> binc <x> depth <x> nodes <x> movetime <x> infinite
- Extended to include
go perft <x>
- Extended to include
stop
quit
In addition to the above UCI commands, Toad also supports the following custom commands:
Commands:
await Await the current search, blocking until it completes
bench Run a benchmark with the provided parameters
changevariant Change the variant of chess being played, or display the current variant
display Print a visual representation of the current board state
eval Print an evaluation of the current position
exit Quit the engine
fen Generate and print a FEN string for the current position
flip Flips the side-to-move. Equivalent to playing a nullmove
hashinfo Display information about the current hash table(s) in the engine
makemove Apply the provided move to the game, if possible
moves Shows all legal moves in the current position, or for a specific piece
option Display the current value of the specified option
perft Performs a perft on the current position at the supplied depth, printing total node count
psqt Outputs the Piece-Square table value for the provided piece at the provided square, scaled with the endgame weight
splitperft Performs a split perft on the current position at the supplied depth
help Print this message or the help of the given subcommand(s)
For specifics on how a command works, run toad <COMMAND> --help
Name | Values | Default | Description |
---|---|---|---|
Clear Hash |
Clear the hash table(s) | ||
Hash |
1..=1024 |
16 |
Set the size (in MB) of the hash table(s) |
Threads |
1..=1 |
1 |
Only implemented for use with OpenBench |
UCI_Chess960 |
true , false |
false |
Enable support for Chess960 |
To run Toad, head over to the releases page to grab the latest pre-compiled release for your platform. Alternatively, you can build from source:
- Ensure you have Rust and Cargo installed.
- Clone this repository:
git clone git@github.com:dannyhammer/toad.git
- Build and run!
or run
cargo run --release
make
to generate an executable namedtoad-<version>
.make ./toad-<version>
Note: Development has primarily been done on Linux (Ubuntu 22.04), with minimal testing on Windows 10 and no testing on MacOS. If you are willing to test the installation and execution of Toad on other operating systems, please provide feedback!
- Core:
- Bitboard representation.
- Magic Bitboards for sliding piece attacks.
- Repetition detection through Zobrist Hashing.
- Chess960 support via the
UCI_Chess960
option orchangevariant
command.
- Search:
- Based on the Negamax algorithm.
- Alpha-Beta Pruning in a fail soft framework.
- Time Management with soft and hard timeouts.
- Quiescence Search in a fail soft framework.
- Draw detection through insufficient material, 2-fold repetition, and the 50-move rule.
- Transposition Table.
- Principal Variation Search.
- Aspiration Windows with gradual widening.
- Null Move Pruning.
- Reverse Futility Pruning.
- Late Move Reductions.
- Check Extensions.
- Transposition Table Cutoffs.
- Move Ordering:
- MVV-LVA with relative piece values
K < P < N < B < R < Q
, soKxR
is ordered beforePxR
. - Hash moves.
- History Heuristic.
- MVV-LVA with relative piece values
- Evaluation:
- Hand-Crafted Evaluation (HCE).
- Material difference.
- Piece-Square Tables with initial values from PeSTO.
- Tapered Evaluation.
- Incrementally-updated board evaluation.
- Hand-Crafted Evaluation (HCE).
More features will be added as development continues! You can see most of my future plans in the backlog.
More people have helped me on this journey than I can track, but I'll name a few notable resources/people here:
- Sebastian Lague, for his chess programming series on YouTube that ultimate inspired me to do this project.
- The Chess Programming Wiki, and all those who contribute to free, open-source knowledge.
- The folks over at the Engine Programming Discord, for their patience with my silly questions and invaluable help overall.
- Analog-Hors, for an excellent article on magic bitboards
- The authors of viridithas and Stormphrax, for allowing their engines to be open source and for answering all my silly questions.
- Andrew Grant for creating OpenBench and being willing to help me with its setup and use.
- The authors of Yukari for motivation through friendly competition.
- Paul T, for feedback on my
uci-parser
crate.