Raphael is a UCI Chess Engine built using C++ and Disservin's Chess Library. It also comes with a GUI built using SFML.
Raphael is a hobby project that is still a work in progress, but it will be updated as time goes by. It has comparable strengths to a human candidate, FIDE, or international master, and performs decently against other CCRL-ranked chess engines. You can scroll to the bottom to see a list of features currently implemented.
Raphael is largely inspired by Sebastian Lague's Coding Adventure series on implementing a Chess Engine, and is a revisit/successor to a previous engine I coded in Python.
Note: v1.8 will be the last of the minor releases to Raphael. The next major release will be v2.0 using a custom NNUE evaluator currently in the works of being trained on evaluations from my own engine.
Estimated CCRL 40/2 ELO: 2084
To estimate Raphael's ELO, I paired it up against several other engines in a 10 rounds 40/2 gauntlet tournament inside of Arena, incrementally updating Raphael's ELO using the this calculator based on the statistical model between win probability and ELO.
Raphaelv1.8 was matched against Claudia (1846), Monarch 1.7 (2008), and BBChess 1.1 (2024), and the results were a WDL of 7-3-0 (+36.8), 6-0-4 (+21.5), and 7-2-1 (+59.9), respectively. Previously, the ELO of Raphaelv1.7.6 was estimated to be around 1966, thus the estimated ELO of Raphaelv1.8 is around 2084.
Note that this method of ELO estimation is very crude, as it only only compares against a few other engines with only 10 rounds. In the future, I will conduct a more thorough comparison.
Past ELOs
Version | CCRL 40/2 |
---|---|
1.8.0 | 2084 |
1.7.6 | 1966 |
1.7.0 | 1865 |
1.6.0 | 1797 |
1.5.0 | 1764 |
Builds for Windows and Ubuntu/WSL are available on the Releases page.
The UCI engine is a standalone executable. The GUI is in main.zip
and should be extracted and kept in the main
folder to ensure the executable can correctly find its dependencies (you may rename the folder). If you are on Ubuntu, please run sudo apt install libsfml-dev
as the build is dynamically linked.
Please see the sections below on how to compile the code yourself if the executables do not work for you.
You can start a quick GUI match against yourself and Raphael as follows:
main.exe human "Human" Raphael "Raphael" -s "game.pgn" # Windows
./main human "Human" Raphael "Raphael" -s "game.pgn" # Ubuntu/WSL
You can see other command-line arguments by running main.exe -h
. The UCI engine has no command-line arguments.
This is the recommended way of compiling Raphael. If you are on Windows, you can install WSL to follow these steps (it may be easier than the compilation steps described in the Windows portion).
-
Clone the repository with
git clone https://github.com/Orbital-Web/Raphael.git --recurse-submodules
-
Ensure you have Make and g++ installed. You can do so by running
sudo apt-get install build-essential sudo apt-get install g++
-
Compile as follows:
make packages # install dependencies (SFML) make main # build GUI make uci # build UCI engine
If Ubuntu/WSL does not work for you, or you would like to compile the code statically, you can follow these steps:
-
Clone the repository with
git clone https://github.com/Orbital-Web/Raphael.git --recurse-submodules
-
Download SFML-2.6.0 GCC 13.1.0 MinGW 64-bit and add it to the root directory
-
Copy
openal32.dll
fromSFML-2.6.0/bin/
and add it to the root directory -
Compile dependencies with the following commands (in the root directory)
cd src/GameEngine g++ -c -O3 -march=native -DNDEBUG consts.cpp GameEngine.cpp GamePlayer.cpp HumanPlayer.cpp utils.cpp -I"../../src" -I"../../chess-library/src" -I"../../SFML-2.6.0/include" -DSFML_STATIC cd ../../src/Raphael g++ -c -O3 -march=native -DNDEBUG consts.cpp History.cpp Killers.cpp SEE.cpp Transposition.cpp -Isrc -Ichess-library/src -I"../../src" -I"../../chess-library/src" -I"../../SFML-2.6.0/include" -DSFML_STATIC cd ../../
-
Compile
main.exe
with the following commands (optionally, compile with the-DMUTEEVAL
flag to mute evaluations)g++ -c -O3 -march=native -DNDEBUG main.cpp -Isrc -Ichess-library/src -I"SFML-2.6.0/include" -DSFML_STATIC g++ -o main main.o src/GameEngine/consts.o src/GameEngine/GameEngine.o src/GameEngine/GamePlayer.o src/GameEngine/HumanPlayer.o src/GameEngine/utils.o src/Raphael/consts.o src/Raphael/History.o src/Raphael/Killers.o src/Raphael/See.o src/Raphael/Transposition.o -L"SFML-2.6.0/lib" -lsfml-graphics-s -lsfml-window-s -lsfml-audio-s -lsfml-system-s -lopengl32 -lfreetype -lwinmm -lgdi32 -lopenal32 -lflac -lvorbisenc -lvorbisfile -lvorbis -logg -static
-
Compile the UCI engine with the following commands
g++ -c -O3 -march=native -DNDEBUG uci.cpp -Isrc -Ichess-library/src -I"SFML-2.6.0/include" -DSFML_STATIC g++ -o uci uci.o src/GameEngine/consts.o src/GameEngine/GamePlayer.o src/Raphael/consts.o src/Raphael/History.o src/Raphael/Killers.o src/Raphael/See.o src/Raphael/Transposition.o -L"SFML-2.6.0/lib" -lsfml-graphics-s -static
The GUI is a quick and easy way to start engine battles or play against Raphael interactively. You can play against Raphael by starting a match against a human player and Raphael engine in the command line (see main.exe -h
).
The human player can move a piece by either dragging and dropping a piece to the destination square, or by clicking a piece and clicking the destination square. Castling can be done by clicking the destination square of the king after castling. Only promotion by queening is currently supported. You can also annotate the board with arrows by holding and dragging the right mouse button.
You can also play with different time controls, increments, and player combinations. Again, please refer to main.exe -h
and the setup instructions above for a more in-depth guide.
Raphael is a UCI-compliant chess engine. To use it in other UCI-compliant softwares, compile uci.cpp
using the instructions above. The UCI engine currently supports the following commands: uci
, isready
, ucinewgame
, stop
, quit
, position
, and go [wtime|btime|winc|binc|depth|nodes|movestogo|movetime|infinite]
. Pondering is not implemented yet in the UCI engine, though it does come in the GUI version. The engine contains the following features:
- Alpha-beta pruning (
v1.0+
) - Move ordering (
v1.0+
) - Transposition table (fix) (
v1.1+
) - Iterative deepening (fix) (
v1.1+
) - Aspiration window (
v1.3+
) - Opening book
- Endgame table
- Quiescence with captures (
v1.0+
) - Quiescence with queening
- Time management (
v1.0+
) - Skip search on stable pv (
v1.6+
) - Pondering (
v1.2+
) - Pondering with pv (
v1.6+
) - Check extensions (
v1.4+
) - Passed pawn extensions (
v1.4+
) - One reply extensions (
v1.7+
) - Late move reductions (
v1.5+
) - Mate distance pruning (
v1.6+
) - SEE pruning (
v1.7+
) - Lazy SMP
- Materials (
v1.0+
) - Piece-square tables (
v1.0+
) - Midgame King safety
- Endgame King opposition
- Endgame King proximity (
v1.0+
) - Evaluation tapering (
v1.0+
) - Passed Pawn (
v1.3+
) - Isolated Pawn (
v1.3+
) - Mobility (
v1.5+
) - Bishop pair (
v1.8+
) - Bishop-colored corner (
v1.8+
) - Draw evaluation (
v1.8+
) - Evaluation tuning (
v1.8+
) - NNUE
- NNUE feature factorization
- NNUE PSQT factorization
- MVV-LVA (
v1.0+
) - Promotions (
v1.0+
) - Hash move (
v1.6+
) - Killer heuristics (
v1.3+
) - History heuristics (
v1.5+
) - SEE (
v1.7+
)
Below is the result of each new version against v1.0
out of 400 matches (20 seconds each), starting from a different position (within a ±300 centipawn stockfish evaluation) and alternating between playing as white and black.
v1.0
v1.0 [177 / 34 / 189]
v1.1
v1.0 [245 / 39 / 116]
v1.2
v1.0 [253 / 34 / 113]
v1.3
v1.0 [301 / 23 / 76]
v1.4
v1.0 [333 / 25 / 42]
v1.5
v1.0 [344 / 23 / 33]
v1.6
v1.0 [355 / 27 / 18]
v1.7
v1.0 [374 / 20 / 6]
v1.8
v1.0 [380 / 16 / 4]
And below are the more detailed comparisons.
Player | Wins | Draws | Losses | Opponent | ||||
---|---|---|---|---|---|---|---|---|
White | Black | Timeout | White | Black | Timeout | |||
v1.0 | 91 | 70 | 16 | 34 | 92 | 70 | 27 | v1.0 |
v1.1 | 94 | 104 | 47 | 39 | 53 | 63 | 0 | v1.0 |
v1.2 | 115 | 104 | 34 | 34 | 62 | 51 | 0 | v1.0 |
v1.2 | 112 | 96 | 6 | 30 | 86 | 61 | 9 | v1.1 |
v1.3 | 144 | 120 | 37 | 23 | 43 | 32 | 1 | v1.0 |
v1.3 | 107 | 107 | 10 | 38 | 61 | 61 | 16 | v1.2 |
v1.4 | 144 | 136 | 53 | 25 | 14 | 27 | 1 | v1.0 |
v1.4 | 117 | 114 | 13 | 40 | 57 | 49 | 10 | v1.3 |
v1.5 | 156 | 154 | 34 | 23 | 15 | 18 | 0 | v1.0 |
v1.5 | 99 | 99 | 13 | 62 | 61 | 60 | 6 | v1.4 |
v1.6 | 169 | 178 | 8 | 27 | 5 | 13 | 0 | v1.0 |
v1.6 | 122 | 127 | 2 | 77 | 33 | 39 | 0 | v1.5 |
v1.7 | 182 | 187 | 5 | 20 | 2 | 4 | 0 | v1.0 |
v1.7 | 92 | 98 | 0 | 108 | 53 | 49 | 0 | v1.6 |
v1.8 | 187 | 191 | 2 | 16 | 2 | 2 | 0 | v1.0 |
v1.8 | 99 | 98 | 0 | 100 | 45 | 53 | 5 | v1.7 |
Note: a timeout usually means that the game was relatively equal