Skip to content
Riadh Mnasri
← Back to blog
4 min read

The Elo Rating: The Algorithm Behind a Self-Correcting Score

The article on Swiss pairings mentioned the Elo rating as a sorting criterion without detailing how that number gets computed. It's actually a full algorithm in its own right, with its own logic and its own pitfalls: a system that predicts a result before it's played, then adjusts based on the gap between the prediction and reality.

The principle: a win probability before the game is even played#

Before a game is played, the Elo system computes an expected score from nothing but the rating gap between the two players:

E_A = 1 / (1 + 10^((R_B - R_A) / 400))

E_A is player A's expected score (a win probability between 0 and 1, where a draw counts as 0.5), R_A and R_B the two players' Elo ratings. With A at 1600 and B at 1400:

E_A = 1 / (1 + 10^((1400 - 1600) / 400))
    = 1 / (1 + 10^(-0.5))
    = 1 / (1 + 0.316)
    ≈ 0.76

A is favored at 76%, B at 24% (E_A + E_B = 1 by construction: whatever probability one gains, the other loses exactly).

The adjustment: what the actual result changes about the rating#

After the game, the new rating depends on the gap between the actual result and the expected one, weighted by a factor K:

R_A' = R_A + K × (S_A - E_A)

S_A is 1 for a win, 0.5 for a draw, 0 for a loss. With K = 20 and A winning (S_A = 1):

R_A' = 1600 + 20 × (1 - 0.76) = 1600 + 4.8 = 1604.8

Had A drawn: 1600 + 20 × (0.5 - 0.76) = 1594.8. Had A lost: 1600 + 20 × (0 - 0.76) = 1584.8. B's rating moves as a mirror image: B loses exactly what A gains (with the same K on both sides), 1400 - 4.8 = 1395.2 in the first case.

The K factor: how fast the rating reacts#

K determines how much a single result moves the rating. A high K moves the rating fast (useful for a player whose true level isn't known yet), a low K stabilizes it (useful for an already well-rated player, where one fluke result shouldn't tank the score).

ProfileTypical KWhy
New player, fewer than about 30 official games40Converge quickly toward a true level that's still unknown
Rated player, general case20The standard trade-off between stability and responsiveness
Player above 2400 Elo10An already stable rating, which one fluke shouldn't be able to crash

Why the system is self-correcting#

On a single game, the gap between expected and actual score can be large. Over dozens of games, that gap averages out: a player who's consistently underrated wins more often than their expected probability predicts, so their rating climbs game after game until it reflects their true strength. It's that property, converging toward true strength without ever knowing it in advance, that makes the system usable for rating thousands of players without any arbiter having to judge their level directly.

The catch: it's only zero-sum if K matches on both sides#

The earlier calculation is exactly zero-sum because A and B shared the same K = 20. That stops being true the moment a new player (K = 40) faces a rated player (K = 20): each computes their own adjustment with their own K, and nothing guarantees that what one gains exactly matches what the other loses. That small mismatch, repeated over millions of mixed games, is one of the mechanisms regularly cited behind the long-term Elo inflation observed in some federations.

Where this plugs into a real tournament system#

It's this number, recomputed after every game, that feeds the rating-based sort used inside the score groups of the Swiss pairing implemented by kotlin-chess-tournament and exposed by EloChessPlanner. The pairing system and the rating system are two distinct algorithms, but neither means much without the other: pairing by Elo only makes sense if the Elo used actually reflects the player's level at the time of the round.