Skip to content

DarkHorse v1.0

Latest

Choose a tag to compare

@CheckersGuy CheckersGuy released this 03 Jul 19:02

DarkHorse logo

DarkHorse is a checkers engine powered by three neural networks to enhance its decision-making:

  • Evaluation Network – Assesses board positions to determine their strategic value.
  • Game-Length Estimator – Predicts how long a game might last from a given position. This helps the engine prefer positions where it is still making progress.
  • Policy Network – Produces a probability distribution over possible moves, improving move-ordering during search.

The neural networks are embedded directly in the binary, so there's no need to download any additional files. Occasionally, small updates may be released if improved networks become available.

Network Architecture

All three networks are small, quantized feed-forward nets designed to run efficiently on CPU during search, using an NNUE-style incremental update scheme rather than a full forward pass on every node.

  • Incremental input layer. The board is encoded as sparse binary features (separate feature planes for white pawns, black pawns, white kings, and black kings across the 32 playable squares). Rather than recomputing the first layer from scratch after every move, an Accumulator tracks the running activation and is updated incrementally — only the features that actually changed (a piece appearing, disappearing, or promoting) are added or subtracted from it. This is the same trick used by NNUE evaluation in modern chess engines, and it's what makes running a neural net at every search node computationally feasible.
  • Bucketed weights. Beyond the input layer, the network's weights are split into buckets indexed by piece count, so the engine effectively uses a different set of learned weights depending on how many pieces remain on the board. This lets the evaluation specialize — the features that matter in a dense, full-board middlegame are quite different from those that matter in a sparse 3-vs-2 king endgame — without needing an entirely separate network per phase.
  • Quantized int8 inference. Weights and activations are quantized to 8-bit integers for the forward pass, using AVX2 SIMD instructions (with sparse/nonzero-index tricks to skip zeroed activations) to keep evaluation fast enough to run millions of times.
  • Evaluation network — the largest of the three, responsible for the core positional score that drives alpha-beta search.
  • Game-length estimator — a much smaller auxiliary network that predicts how many moves remain until a decisive result. Its output is blended into the evaluation once a position becomes sufficiently one-sided, biasing the engine toward continuing to make progress rather than shuffling pieces once it already has a winning advantage.
  • Policy network — outputs a score per legal move that is used to order moves. There is no other no move-ordering provided like via a history heuristic, killer moves etc. like one would find in a traditional alpha-beta engine.

All three networks are trained separately in PyTorch on data generated by DarkHorse's own self-play pipeline, then exported and quantized for inference in the C++ engine.

The excellent nnue-pytorch documentation from the Stockfish team was extremely helpful while working on the inference code for the neural network, particularly the accumulator-based incremental update scheme and the general approach to quantized int8 inference.

Thanks to all the other engine authors whose work served as a valuable inspiration throughout this project

  • Martin Fierz — Author of the powerful checkers program Cake and the excellent CheckerBoard GUI. The story behind the making of Cake 1.86–1.89 was what finally motivated me to finish the project and create this release.
  • Ed Gilbert — Creator of the strong checkers engine Kingsrow.
  • Jonathan Kreuzer — Developer of the advanced checkers engine GuiNN, which also uses a neural network for position evaluation.