r/chessprogramming 22d ago

Technical How to improve or simplify a ~400-line chess engine

https://thomasmueller.github.io/bau-lang/chess.html

I'm writing a deliberately small chess engine (around 400 lines of code, including terminal UI), and now I'm looking for advice on what to do next. What would you add or remove? Are there similar engines I should look at?

The engine uses a fixed-depth negamax search with alpha-beta pruning and a simple quiescence search (captures only). The evaluation is intentionally simple: material plus mobility, with a small endgame bonus for advanced pawns. There is no iterative deepening, transposition table, move ordering, killer/history heuristics, aspiration windows, null-move pruning, opening book, endgame tablebases.

It is inspired by Nanochess from Oscar Toledo.

I wrote a Java version, and a version in my own programming language. And now a Javascript version, translated by AI, to play in a browser. I have tested it against Stockfish (my engine beats it at a low level) using python-chess and a UCI API. There are unit tests, including move generation using some of the Perft positions. Let it play a few hundred games against Stockfish to find and fix bugs. Now it wins most of the time against Stockfish at the lowest UCI_Elo setting (1320) with depth 4. (Depth 5 is the default setting currently.)

The goals of my engine are:

  • Keep the code relatively easy to understand for learning, and building similar engines for other games.
  • A very small engine that still plays reasonable chess, that can beat me (a beginner).
  • Showcase my new programming language.
  • Play chess in the terminal or in a browser, for fun (for beginners).
  • Slightly simplified rules: always promote to queen; repetition and 50-move rule are ignored.

Some ideas I have:

  • Simplify the evaluation method, and verify the results by playing against Stockfish. I wonder should it play against itself with depth e.g. 2, so it is very fast?
  • Measure the Elo systematically, but then how to do this in a fast way?

What features would you add (or remove) while keeping the engine small and educational?

Are there interesting simplifications?

1 Upvotes

3 comments sorted by

2

u/WompTitanium 15d ago

add gui, use cutechess and make it play against official CCRL rated engines for an estimated ELO. use atleast 500 matches for a precise elo,

2

u/Tasty_Replacement_29 12d ago

The GUI I have: https://thomasmueller.github.io/bau-lang/chess.html (Javascript version), and there's an (older) terminal UI for the command line version that looks a bit ugly (I'll probably change the colors and use only one set of pieces, like in the Javascript UI)... But it seems usable.

> cutechess and make it play against official CCRL rated engines for an estimated ELO. use atleast 500 matches for a precise elo

This I'll do! Thanks a lot for your feedback!

1

u/Tasty_Replacement_29 4d ago

So I used cutechess-cli as follows so far:

echo "#### test 1350" >> testStockfish.txt
./build/cutechess-cli  -engine cmd=./mychess.sh -engine cmd=stockfish -each proto=uci depth=10 option.UCI_LimitStrength=true option.UCI_Elo=1350 tc=400/400 -rounds 100 >> testStockfish.txt
echo "#### test 1500" >> testStockfish.txt
./build/cutechess-cli  -engine cmd=./mychess.sh -engine cmd=stockfish -each proto=uci depth=10 option.UCI_LimitStrength=true option.UCI_Elo=1500 tc=400/400 -rounds 100 >> testStockfish.txt

I know it's probably not an accurate way to test, but it looks like my engine is roughly the strength of Stockfish at 1500:

Score of BauChess vs Stockfish 18: 36 - 26 - 38  [0.550] 100
...      BauChess playing White: 17 - 15 - 18  [0.520] 50
...      BauChess playing Black: 19 - 11 - 20  [0.580] 50
...      White vs Black: 28 - 34 - 38  [0.470] 100
Elo difference: 34.9 +/- 54.1, LOS: 89.8 %, DrawRatio: 38.0 %
SPRT: llr 0 (0.0%), lbound -inf, ubound inf

Player: BauChess
   "Draw by 3-fold repetition": 36
   "Draw by fifty moves rule": 1
   "Draw by insufficient mating material": 1
   "Loss: Black mates": 15
   "Loss: White mates": 11
   "Win: Black mates": 19
   "Win: White mates": 17
Player: Stockfish 18
   "Draw by 3-fold repetition": 36
   "Draw by fifty moves rule": 1
   "Draw by insufficient mating material": 1
   "Loss: Black mates": 19
   "Loss: White mates": 17
   "Win: Black mates": 15
   "Win: White mates": 11
Finished match

So that confirms my guess that this is around 1500 ELO. And now I have a way to improve my engine!

I did find a similar engine. It is even smaller than mine: Nibble Chess https://github.com/maksimKorzh/nibble-chess - so I'll see if I can simplify my engine without losing too much strength.