AI Chess

When The Eval Says Plus Three And You Still Can’t Win It

You know the feeling. Move 28 of a 15+10 rapid game, you’ve won a piece, and after the game Lichess paints that beautiful cliff on the eval graph: 0.3 into 3.4. Then forty minutes of your life disappear and the game ends in a draw, or worse. The engine was right. You were also right that you had no idea what to do. Both facts can live in the same position, and the space between them is where most club-level rating actually hides.

Here is the thing nobody tells you when they hand you Stockfish. A +3.40 is not a description of the position. It’s a prediction, and it carries a hidden clause: assuming both sides continue to play like Stockfish. Change the player and you change the number. You are not Stockfish. Nobody at 1400 is Stockfish, and nobody at 2400 is either.

What the number is actually claiming

Stockfish since version 12 evaluates with a neural network (NNUE), and the output has been normalized so that roughly +1.00 corresponds to about a 50% chance of winning from there at engine strength. That calibration is worth sitting with. At +1.00, a coin flip. By +3.00 you are deep into near-certainty territory for an engine, which is why the bar on your screen goes almost entirely white and your brain reads it as “won.”

Leela Chess Zero is more honest about this and reports win/draw/loss probabilities directly, three numbers instead of one. Lichess does something similar by translating centipawns into a win percentage on the graph. Either way the probability belongs to the engine, not to you, and if you want the full tour of what those numbers do and don’t encode, Reading Engine Output: Evals, Depth And Lies covers the machinery. For now, one rewrite is enough: +3.00 means an engine would win this. It says nothing about whether you would.

Measure your gap before you try to close it

Converting winning chess positions is a skill with a number attached, and you can compute yours this afternoon. Pull your games with evals from the Lichess API:

https://lichess.org/api/games/user/YOURNAME?evals=true&max=300&perfType=rapid

Then count how often you reached a clearly winning position and how often you actually won it:

import chess.pgn

ME = "yourname"
THRESHOLD = 200  # centipawns: +2.00

reached = won = 0
with open("rapid.pgn") as f:
    while (game := chess.pgn.read_game(f)) is not None:
        me_white = game.headers["White"] == ME
        peak = -10000
        for node in game.mainline():
            ev = node.eval()
            if ev is None:
                continue
            cp = ev.white().score(mate_score=10000)
            peak = max(peak, cp if me_white else -cp)
        if peak >= THRESHOLD:
            reached += 1
            if game.headers["Result"] == ("1-0" if me_white else "0-1"):
                won += 1

print(f"{won}/{reached} = {won / reached:.0%}")

A typical 1400 who runs this comes back with something like 34/52, which is 65%. Stockfish converts +2.00 at essentially 100%. Those 18 non-wins are not 18 blunders in the normal sense: they are 18 occasions where the position was solved and the solver wasn’t there. Depending on how they split between draws and losses, that’s somewhere north of 100 rating points sitting in a bucket you have never once trained.

Run it again at THRESHOLD = 500. If your conversion rate at +5.00 is also 65%, you don’t have a technique problem, you have an attention problem, and the fix is clock management rather than endgame study. The two failures look identical on the graph and need opposite medicine.

The three species of unwinnable plus three

The tightrope. The eval is real but it sits on one move, and the second-best move hands most of it back. You can detect this in about fifteen seconds. Set your engine to show more than one line (setoption name MultiPV value 5 over UCI, or just the multi-line toggle in Nibbler or the Lichess analysis panel) and read the spread:

Position APosition B
Best move+3.10+4.50
2nd best+3.05+0.25
3rd best+2.80+0.10
Verdictwide, playabletightrope

Position A is worth three pawns to you. Position B is worth three pawns to a machine and about a quarter of a pawn to a human with eleven minutes left. This leads to the single most useful habit in this whole article: in a real game, trading a +4.50 tightrope for a +2.20 position with a wide margin of error is not cowardice, it is correct play. Your practical expectancy goes up. The eval goes down. Let it.

The technique you don’t own. Bishop and knight against a lone king is a forced mate in at most 33 moves. It is also a mate that a large majority of players under 1900 cannot deliver inside the fifty-move rule, because the method (drive the king to the wrong-coloured corner using the knight to build a barrier) has to be known, not found. Queen against rook is a tablebase win in no more than 31 moves and is genuinely hard: strong titled players have failed to convert it on the clock. Rook and pawn versus rook splits into a Lucena (win, via building a bridge with the rook on the fourth rank) and a Philidor (draw, via the defending rook on the third rank), and they look nearly identical to an untrained eye. The engine prints +5.2 for one and 0.00 for the other and offers no hint that your entire result depends on recognising which room you walked into.

The eval that’s just wrong at your depth. Fortresses, blocked structures, bishop-versus-wrong-coloured-rook-pawn setups. Stockfish at depth 22 will cheerfully tell you +3.60 in a position that is a dead draw, and only at depth 40-plus (or with tablebases loaded) does the number collapse to zero. Point your engine at Syzygy files (setoption name SyzygyPath value /path/to/syzygy) and the seven-piece endings stop being opinions. The five-piece set is under a gigabyte; six-piece is around 150 GB, which is why Lichess hosts the lookup for you at lichess.org/tablebase.

Analysis that trains conversion instead of admiring it

Most post-game analysis stops at the blunder. That’s the wrong anchor entirely. Find instead the last position in which you were still above +2.00, because everything after it is noise and everything before it is irrelevant to this particular weakness. Copy that FEN.

Now do four things with it.

Play it out, three times, against something that resists like a human. Lichess’s Maia bots were trained on human games at specific strengths: maia1 plays around 1100, maia5 around 1500, maia9 around 1900. They make the mistakes your actual opponents make, in the places your actual opponents make them, which is why beating Maia five times teaches you more than beating Stockfish level 4 once. If you prefer a dialled-down Stockfish, use UCI_LimitStrength with UCI_Elo (the usable range in recent versions runs from about 1320 to 3190) rather than the skill-level slider, which produces weird random lurches instead of consistent play. Rule: three wins out of three before the position leaves your list.

Write the method as one sentence before touching a piece. Not a move, a sentence. “Trade the rooks and keep the bishops, walk the king to c5, then push a4-a5.” If you can’t write it, you don’t have a plan, you have a hope, and hope costs about twenty minutes on the clock. Do this ten times and you’ll notice your sentences getting shorter and more mechanical, which is what technique feels like from the inside.

Measure the forgiveness width with MultiPV and note it next to the position. Over fifty positions you’ll build a real intuition for which winning positions are worth steering toward.

Then file it. A Lichess Study with one chapter per position, each chapter set to Practice with computer and a goal of “win,” gives you a drill set that reloads in one click. Ten chapters is a week. Fifty chapters is the difference between 65% and 85% conversion, and 85% conversion at club level is a different rating band.

The person who beats you from a lost position is rarely playing better chess than you. They’re playing a position you never practised, against a clock you forgot about, while your eval bar sat there glowing white and telling you a true thing about somebody else’s game. Go pull your last thirty rapid games, run the script, and find out what your number is.