Chess players know the ritual: The game ends, and immediately you’re scrolling back through the moves, wondering where it went right (or very wrong). We brought that same instinct to Duolingo with the launch of Chess Game Review: a feature that helps learners understand their games without burying them in engine noise.
From the start, we made a deliberate choice to avoid the information overload that so many improving players run into, where every single move gets annotated and dissected. Instead, we focus on the key takeaways. We wanted to show players that you don’t have to play perfectly, you just need to play better than your opponent.
Behind that simple, friendly interface is a surprisingly deep set of engineering and machine learning problems: How do you decide which of the 40-plus moves in a game actually matter? How do you tell the difference between a “mistake” and a “blunder”? And how do you get a chess engine to recognize a brilliant move the way a human would, including ones a purely optimal engine would never even consider playing?
This post is a peek behind the curtain at how we built it—the evaluation systems we borrowed from competitive chess, the ones we invented ourselves, and the neural networks doing the heavy lifting in between.
The most common method of evaluation: pawns and centipawns
Pawns
Traditionally, chess players use points as the units of material evaluations. The most popular method assigns 1 point to a pawn, 3 to a knight or a bishop, 5 to a rook, and 9 to a queen. Kings normally do not have values assigned, since they cannot be captured and a checkmate ends the game.
For example, if you took your opponent’s rook with your bishop, and they captured the bishop back, you have gained 5 points from the rook and lost 3 points from your bishop for a net gain of 2 points.
There are a lot of variations, though—for example, people have debated for centuries whether a queen is worth 9 points, 10 points, 8.5 points, or 9.94 points (!). The 1/3/5/9 system, however, is by far the most popular and is considered the “universal language.”
You might have noticed that pawns are assigned 1 point—which is why you’ll sometimes hear the word “pawns” being used interchangeably with “points.” For example, if you trade a bishop for three pawns, it is roughly equivalent, although practically, such imbalanced positions are difficult to evaluate—we’ll talk more about these later!
Chess players use these values for evaluating different positions, too: For example, perhaps you are not ahead in material, but your position is so superior that you are the equivalent of 3 points—a bishop—ahead, in which case you can say “I am plus 3” (in other words, 3 points ahead) without actually having an extra bishop.
Centipawns
While the point system described above is useful, it is also too coarse-grained. The difference between a well-played move and a weak move is often obvious, but less than a pawn’s worth. For example, White can move any of the pawns one or two squares as the first move, but it turns out that other than one move (the infamously tricky but objectively bad Grob’s Opening), all others are within 1 pawn’s worth, and most are within 0.5 pawns’ worth.
To be able to differentiate between such moves and board positions, centipawns—1/100 of a pawn—are the most frequently used point system by chess engines.
The most common way of evaluating a chess move is the centipawn loss—how many centipawns one loses after a move, and the average centipawn loss across all moves for a player in a game is a rough depiction of how well they played.
Note that since centipawn evaluations already assume best play from both players, from one player’s point of view it would never go up after their move. For example, a perfect move would have a centipawn (or CP) loss of 0, a well-played top-level Grandmaster game would have an average loss below 10 CP, and a strong amateur game might have an average loss below 30 CP.
One might think a good way of determining if a move is a mistake or a blunder would be to look at the centipawn loss of the move—surely a 500 CP drop would be a blunder? However, a few things complicate this, including (but not limited to):
- Checkmate values: If a player has the opportunity to checkmate the opponent in a few moves, then standard centipawn evaluation doesn’t apply anymore, and the evaluation should be in the form of how many moves until checkmate. Practically speaking, we can use a checkmate value to convert this into a centipawn evaluation by arbitrarily choosing a high value (typically something like 10,000), but it doesn’t fit the rest of the system naturally. For example, if you missed a checkmate but are still up a queen, your evaluation might go from close to 10,000 to 1,000, but that’s probably not a blunder since you are still ahead and likely to win.
- Winning and losing positions: Centipawns don’t have a notion of “difficulty,” and one of the best illustrative examples is winning or losing positions. For example, if you have a queen and 2 pawns and your opponent has 1 rook and 1 pawn, trading the queen for the rook and pawn would virtually guarantee a win, and is probably the most practical move since there is no chance to go wrong and lose. However, chess engines might think that’s a large centipawn loss since you are now only ahead by 2 pawns. These would apply whenever one is winning or losing by a significant amount.
How do we solve this without overcomplicating the system with a lot of branches? Well, that’s where we’re going next!
How mistakes and blunders are found: Win-Draw-Loss
As mentioned above, the centipawn system is not great for evaluating mistakes or blunders. Instead, we can use something called Win-Draw-Loss, which is the standard metric used for move classification.
As its name suggests, Win-Draw-Loss (or WDL) is a combination of three values: the probability of winning, the probability of a draw, and the probability of losing. A win scores 1 point, a loss 0, and a draw 0.5, and we can use these to calculate a player’s expected WDL value, referred to as E(WDL), which is another way of evaluating a player’s position.
Using probabilities for evaluation is an old idea. However, it didn’t gain popularity until the creation of the AlphaZero chess engine: Compared with earlier chess engines that use handcrafted, knowledge-based evaluations, AlphaZero uses a neural network for position evaluation. AlphaZero directly estimates the WDL of each position and uses it to guide its play.
Compared to the centipawn system, E(WDL) handles lopsided evaluations automatically: For the examples before, truly winning positions and positions that contain checkmate sequences are both close to 1.
This also means E(WDL) is a lot less sensitive around equality, so going from equal to “ahead by a piece” changes the E(WDL) a lot more than “ahead by two bishops.”
In fact, although chess players might be used to seeing the centipawn values produced by modern chess engines such as Stockfish NNUE, those values are more tied to WDL than actual “pawn” values—Stockfish now uses a neural network for evaluation (hence “NNUE”), and a centipawn value of 1.0 means that in self-play it would win 50% of the time, and presumably draw the other 50% (it shouldn’t really lose since it is in a better position), which would be an E(WDL) of 0.75.
So, we can reverse the calculation, and rederive E(WDL) from the centipawn value given by a chess engine. The conversion between E(WDL) to centipawn is characterized by a sigmoidal curve.
One more interesting thing is that the conversion can be chosen differently based on different players. To put it simply, if a Grandmaster is ahead by a bishop, all else being equal, they are going to win 100% of the time, whereas for a beginner it is still probably close to 50/50.
So before these technical topics lull you to sleep, the main takeaway of this section is: We use changes in E(WDL) to define what’s a mistake and what’s a blunder, and we take the user’s level into account while doing so.
Now, you might wonder: These handle all the “bad” moves, but what about the “good” ones? And since we are still using chess engines’ evaluations as input, aren’t we still reviewing games through a non-human-like lens? Well, I’m glad you asked!
Great, brilliant, and beyond: Enter the neural network
Brilliant chess moves have always been an important part of chess lore. People strive for them, write books about them, prizes are given for them, and one legend tells of spectators showering the board with gold coins after such a move.
However, how is a brilliant move defined? We can define them as unexpectedly strong moves: unexpected because a move that’s easy to find isn’t impressive, and strong because they have to either win outright or present difficult practical problems.
A brilliant move can be a sacrifice, but not necessarily so.
Veselin Topalov vs. Alexei Shirov, Linares 1988: The bishop moved from f5 to h3 allowing it to be captured “for free,” while it is actually the only move that wins. Some people think it is one of the best chess moves ever!
AlphaZero vs. Stockfish 8, 2017: The queen moved from h4 to h1, which is an amazing non-sacrificial move that completely paralyzed the strongest classical chess engine at the time. It is considered by many to herald the arrival of the era of neural network based chess engines.You might think these are nebulous terms, but at Duolingo, we think we got a chance to push the state of the art here!
One of the most interesting advancements in chess engine technology in the past few years is the Maia series of chess engines and their ilk. These are trained on human games, and are optimized for predicting human move probabilities instead of best play, and they could be modified to predict things like WDL from a human-like point of view.
And here at Duolingo, we actually hired the main creator of the original Maia engine, Reid McIlroy-Young! We’ve been running our own model training, so most games you play against Oscar are backed by a family of human-like neural networks parameterized by things like rating strength, and we can use it to produce human-like move probabilities and WDL.
Using the ideas above, a move can be classified as brilliant if the probability assigned to all good moves together is small—meaning the right moves were difficult to find—and the user found one (for example, the first brilliant move above).
Another category of brilliant moves is if the move the user played is a good move, had a low probability, and their E(WDL) jumps because of it. This means that, while there might have been other good moves, the move was a good one that posed difficult practical problems for the opponent.
Botvinnik vs. Tal, World Championship 1960, Game 6: A young Tal (nicknamed “The Magician from Riga,” sacrificed his knight for a spectacular speculative attack! Modern engines think white is better to begin with and retreating the knight is preferred, but Botvinnik could not navigate the complexity and lost.There are many other ways we can integrate our human-like neural engines with traditional engines and use insights from both for classifying moves as brilliant, and it doesn’t even end there! Eventually, if we can get the neural engines to be good enough predictors, we can rely on them even more and start regarding mistakes that are extremely difficult for humans to take advantage of as practically good moves.
The rest of the Owlscar
Whew, that’s a lot! However, that has barely scratched the surface. Chess Game Review has already grown into a complicated system, and we have our work cut out for us pushing the boundary of reliable hybrid neural symbolic AI systems, and building out a coach that works with you instead of overwhelming you.
Here are just a few future directions we’re exploring:
- There is a large gray area between “good” and “bad.” If your move is objectively not the strongest, but confuses your opponent who had little time, is it good? There’s a lot of information we can bring in to make Game Review more informative.
- “Key” moments are nice, but we recognize that there are a lot more “teachable” moments than just these few. Maybe a move wasn’t strictly important, but is still something a player can learn from.
- Of course, there is the large space of work where we can improve both our knowledge base and our neural network.
More key moments to come!
Building Game Review meant sitting at the intersection of classical chess theory, modern neural network research, and product design. We had to figure out not only how to evaluate a position, but how to explain it to a learner in a way that actually helps them improve. It’s the kind of problem-solving we get to do across every subject at Duolingo, and we’re just getting started.
If tackling problems like this sounds exciting, we’re hiring. Come help us build the next generation of Duolingo’s learning experiences.