Chess Monte Carlo Simulation
Tracking the 2026 Candidates with dynamic player strength, one million simulated tournaments per round.
Inspired by a Reddit post on tournament modeling, I built a Chess Monte Carlo simulation engine to track the 2026 Candidates. Static pre-tournament ratings can go stale over a high-pressure, three-week event, so the model treats player strength as dynamic and updates ratings in real time as games are played.
Live dashboards
The simulation engine
The engine is written in C++ and simulates the rest of the tournament one million times after each round.
- Form extrapolation finds players on an upswing from velocity trends in their Classical, Rapid, and Blitz histories, and credits momentum across all three time controls instead of reading only the headline classical number.
- Dynamic aggression replaces fixed draw rates with rates that depend on the standings: a leader’s incentive to draw rises near the finish line, trailing contenders must take risks, and eliminated players may coast toward safer play.
- I tuned the hyperparameters with Optuna against historical data from the 2022 and 2024 Candidates, looking for the Pareto balance between per-game accuracy and final-leaderboard accuracy.
Monte Carlo simulation
The interactive dashboard shows the tournament’s “multiverse”, the full distribution of futures consistent with what has happened so far.
The win-probability timeline tracks each player’s chance of winning the tournament round by round, so you can see the exact moment a leader pulls away or a contender collapses.
The rank distribution heatmap goes past “who wins?” to show where each player is likely to finish, which picks out players who are safe in the top half even when the title is out of reach.
The Scenario Explorer
The Scenario Explorer is an interactive decision tree for “what if?” questions about the rest of the tournament.
Before exploring branches, the engine works out who is still mathematically alive. A 4-phase algorithm (max reachable points, then a per-game guaranteed floor, then 1M uniform samples, then exhaustive DFS) separates contenders from eliminated players, so the tree only branches on outcomes that matter. A naive max-points check is not enough. In the figure below, Divya and Tan Zhongyi could on paper climb from 5 to the leader’s current 7 in the two remaining rounds, but the fixed Round 13 and 14 pairings already guarantee the leader at least 7.5, so the deeper phases rule them out.
In the decision tree you navigate branches of hypothetical results and watch how specific outcomes change each player’s remaining win conditions, which shows which games carry the tournament.
For trailing players, a miracle-path search uses a weighted random path sampler to find likely revival routes first, then falls back to exhaustive DFS for low-probability scenarios or forced tiebreak paths.
Acknowledgements
- Inspired by Thomas Dondorf’s Reddit posts on Candidates simulations.
- Tournament schedules and live results via the Lichess broadcast API.
- Player ratings and rating histories via FIDE.
- Model design and C++/Python implementation developed with help from Google Gemini and Anthropic Claude.
- Interactive dashboard designed with Claude via the
/frontend-designskill.