Research · Formula v1.0
The Viveka score: fitting a mental move-ranking formula to Stockfish
Sigmoid Vedanta Technologies · October 2026 · Companion to the book and the online calculator
Abstract
We ask how much of a chess engine's move choice a player can reproduce with arithmetic done in the head. Stockfish 19 scored every legal move in 11,100 positions (3,37,607 moves). From 33 candidate features, each readable from the board without calculating variations, greedy forward selection under opening-grouped cross-validation chose six. Their conditional-logit weights, rounded to integers with a pawn worth ten points, give the Viveka score:
On 3,000 positions from openings never used in fitting, the top-scored move loses 74 cp on average against the engine's best (random move: 345 cp). It is within 50 cp of the best in 69% of positions and a blunder by Lichess's definition in 9.6%. On 2,100 positions from published games of Magnus Carlsen and his opponents it loses 99 cp. Rounding the weights to memorable integers costs nothing measurable. We report the failure modes, which cluster in positions with forcing moves.
1. The problem
Let P be a position, L(P) its legal moves, and s(m) the engine's evaluation in centipawns after move m, from the mover's side. The loss of a move is
Because a centipawn matters more at equality than when one side is winning, we also measure loss in winning chances, using the logistic curve Lichess fits to game outcomes:
We look for a scoring rule V(m) = Σi wi·xi(m), with few features xi that a player can evaluate at the board and small integer weights wi, that minimises the expected winning chances given away by playing its top-scored move:
This is the question Point Count Chess (Horowitz & Mott-Smith, 1960) answered by assertion, Shannon (1950) answered with “rough estimate[s]” for a machine, and Kaufman (1999) answered with data for material alone. Two differences matter here. We score moves, not positions, which matches the decision a player actually makes. And every weight is estimated and tested out of sample.
2. Data and labels
- Engine games. 19,070 positions from Stockfish self-play in 63 common openings, balanced across opening, middlegame and endgame. The openings were shuffled with a fixed seed. 6,000 positions from 42 openings form the training set and 3,000 from the other 21 the test set, so no game contributes to both.
- Human games. 2,100 positions sampled from published games of Magnus Carlsen and his opponents (at most two per game, one per phase, after move 4; Chess960 games excluded). Test only.
- Labels. Stockfish 19, one thread, 64 MB hash, depth 14, MultiPV = |L(P)|, so every legal move gets its own principal variation and score. Mates map to ±(10,000 − plies).
Label noise. An engine at depth 14 is itself an estimate. Against the stored depth-22 analysis of 5,932 training positions, the depth-14 best move agrees 62% of the time, and when it disagrees the median cost is 4 cp. Exact-match rates should be read against this ceiling. Loss-based metrics are barely affected.
3. Candidate terms
Each candidate term had to be computable without a calculation tree. The central one is material after exchanges. For a square q holding a piece of value v, the static exchange value for the side starting the capture is defined by the recursion
where SEE′ is the same quantity for the opponent after the cheapest attacker has captured, so vq becomes that attacker's value and x-ray attackers are revealed. Then
That is: what the move takes, minus the most the opponent can then win by an exchange on any single piece. This is the “blunder check” written as arithmetic. The other selected terms are C = value captured, K = 1 for a check by a piece that is safe under the one-step rule, D = 1 when a knight or bishop leaves its home square or the king castles, A = squares attacked by the moved piece after the move minus before, and W = 1 for a non-castling king move before the endgame. The pool also held a one-step version of M, threats, double attacks, centralisation, passed-pawn pushes, pawn-shield pushes, rook to an open file, early queen moves, king-zone attacks, recaptures and “allows mate in one”.
4. Fitting: a conditional logit
Equation (4) is piecewise constant in w, so we fit a smooth surrogate. Treat the engine's evaluations as a soft choice over the legal moves,
and model the probability of choosing m with McFadden's conditional logit, the standard model for choosing one option from a set:
We minimise the cross-entropy plus a small ridge penalty over the training positions:
J is convex, so L-BFGS finds the global minimum. τ sets how much credit near-equal moves share. A move 3 points of winning chances worse than the best gets e−1 of its weight. The fitted model is only a device for estimating weights; players use the rounded integers.
5. Selecting terms and rounding
Starting from no terms, we repeatedly added the candidate that most reduced the cross-validated objective (4). We used 5 folds, with whole openings held out together so that no game leaks between folds. We kept the smallest number of terms within 5% of the best value on the path, a rule fixed before running the selection.
| k | Term added | CV win-% lost |
|---|---|---|
| 1 | Material | 7.862 |
| 2 | Capture | 6.964 |
| 3 | Safe check | 6.474 |
| 4 | Development | 6.029 |
| 5 | Activity | 5.724 |
| 6 | King walk | 5.634 |
| 7 | Develops a minor piece | 5.541 |
| 8 | Recapture | 5.497 |
| 9 | Allows mate | 5.421 |
| 10 | Early queen move | 5.379 |

We then scaled the six fitted weights so that the material weight is 10 (a pawn is 10 points), rounded them to integers, polished them by integer coordinate search on the training set, and finally rounded them to the nearest memorable values. Under the same cross-validation the published weights give away 5.77 win-% points per move, against 5.71 for the fitted integers. The difference is far inside the fold-to-fold spread (±0.82).
| Term | Fitted weight | Scaled (pawn = 10) | Fitted integer | Published |
|---|---|---|---|---|
| Material | 0.931 | 10.0 | 10 | 10 |
| Capture | 0.182 | 2.0 | 2 | 2 |
| Safe check | 1.015 | 10.9 | 11 | 10 |
| Development | 0.575 | 6.2 | 6 | 5 |
| Activity | 0.044 | 0.5 | 1 | 1 |
| King walk | -0.689 | -7.4 | -7 | -5 |
6. Results
Everything below is measured on positions never used for selection or fitting. Ties between top-scored moves are broken uniformly at random, and we report the expectation. “Blunder” is a drop of at least 15 win-% points (Lichess's threshold).
6.1 Held-out openings
| Move chosen by | Mean loss (cp) | Median | Win-% lost | ≤ 50 cp | Blunder | = SF #1 | SF #1 in top 3 |
|---|---|---|---|---|---|---|---|
| Captures first (largest capture) | 364 | 325 | 21.98 | 35% | 51.0% | 14% | 29% |
| Random legal move | 345 | 283 | 20.73 | 30% | 46.9% | 6% | 17% |
| Material only, one-step rule | 129 | 70 | 8.71 | 54% | 18.6% | 19% | 37% |
| Viveka quick: 10M + 2C + 10K | 87 | 43 | 6.00 | 63% | 11.3% | 24% | 43% |
| Viveka score (published integers) | 74 | 22 | 5.12 | 69% | 9.6% | 28% | 51% |
| Same six terms, fitted real weights | 73 | 20 | 5.04 | 70% | 9.4% | 28% | 52% |
| All candidate terms (linear ceiling) | 72 | 15 | 4.90 | 70% | 9.4% | 30% | 56% |
| Stockfish depth 1 (reference) | 45 | 4 | 2.87 | 84% | 4.5% | 43% | 74% |
| Stockfish depth 4 (reference) | 27 | 2 | 1.67 | 90% | 2.2% | 47% | 78% |

6.2 Real games
| Move chosen by | Mean loss (cp) | Median | Win-% lost | ≤ 50 cp | Blunder | = SF #1 | SF #1 in top 3 |
|---|---|---|---|---|---|---|---|
| Random legal move | 387 | 316 | 23.14 | 24% | 51.2% | 5% | 15% |
| Captures first (largest capture) | 373 | 330 | 22.72 | 33% | 50.8% | 16% | 30% |
| Material only, one-step rule | 149 | 82 | 9.70 | 51% | 20.8% | 21% | 38% |
| Viveka quick: 10M + 2C + 10K | 107 | 49 | 6.87 | 59% | 13.7% | 26% | 44% |
| Same six terms, fitted real weights | 100 | 25 | 6.25 | 65% | 12.6% | 28% | 50% |
| Viveka score (published integers) | 99 | 26 | 6.24 | 65% | 12.5% | 28% | 49% |
| All candidate terms (linear ceiling) | 96 | 22 | 6.15 | 65% | 12.1% | 30% | 53% |
| Stockfish depth 1 (reference) | 42 | 1 | 2.54 | 83% | 4.3% | 50% | 77% |
| Stockfish depth 4 (reference) | 30 | 1 | 1.73 | 88% | 2.1% | 51% | 80% |
| Move actually played in the game | 23 | 0 | 1.26 | 90% | 1.3% | 58% | — |
The formula transfers from engine games to human games. The grandmasters' own moves, many played at rapid and blitz time controls, remain far better. The formula's first choice equals the move played in 30% of positions; Stockfish's first choice equals it in 55%.
6.3 By phase and by how much the choice matters

In calm positions (engine's best and second-best within 30 cp) the formula's average loss is 52 cp. In critical positions (the best move at least 100 cp better than any other) it is 174 cp, and the formula finds the only move in 62% of them.
6.4 The decision a player actually faces
Players score a handful of candidates, not every legal move. We simulated candidate lists of size k that contain the engine's best move. The other k−1 were drawn either from all legal moves (“random”) or from the engine's top eight (“plausible”).
| Set | Other candidates | k | Formula picks the best | Guessing | Mean loss (cp) |
|---|---|---|---|---|---|
| held-out openings | random | 2 | 81% | 51% | 25 |
| held-out openings | random | 3 | 69% | 34% | 42 |
| held-out openings | random | 4 | 62% | 26% | 46 |
| held-out openings | random | 5 | 56% | 21% | 52 |
| held-out openings | plausible | 2 | 68% | 52% | 23 |
| held-out openings | plausible | 3 | 54% | 35% | 31 |
| held-out openings | plausible | 4 | 46% | 27% | 36 |
| held-out openings | plausible | 5 | 40% | 23% | 37 |
| Carlsen games | random | 2 | 81% | 50% | 35 |
| Carlsen games | random | 3 | 69% | 34% | 54 |
| Carlsen games | random | 4 | 63% | 26% | 60 |
| Carlsen games | random | 5 | 57% | 21% | 69 |
| Carlsen games | plausible | 2 | 67% | 51% | 30 |
| Carlsen games | plausible | 3 | 53% | 35% | 42 |
| Carlsen games | plausible | 4 | 45% | 26% | 47 |
| Carlsen games | plausible | 5 | 40% | 22% | 50 |

6.5 Ablation and ties
Removing one term at a time from the published formula (all test positions) raises the average loss by:
- Material: +197.7 cp (+11.26 win-% points)
- Capture: +2.8 cp (+0.23 win-% points)
- Safe check: +6.9 cp (+0.39 win-% points)
- Development: +3.2 cp (+0.31 win-% points)
- Activity: +4.7 cp (+0.33 win-% points)
- King walk: +1.0 cp (+0.06 win-% points)
Integer scores tie often. Tie-break rules (prefer captures, checks, central or active moves, forward moves) moved the average loss by at most 1.3 cp, so the advice is simply to play either.
6.6 Failure analysis
In 21% of test positions the formula's choice loses more than 100 cp. Classifying these by the engine's own lines: the formula missed a forcing win in 18% of them, walked into a forcing reply (fork, pin, discovery) in 28%, faced both in 27%, and misjudged a quiet, positional choice in 27%. Most large errors happen where forcing moves exist, so the practical rule is: use the formula to rank candidates, and calculate forcing lines.
7. What the data says about chess
Regressing the engine's evaluation on material differences in 13,513 quiet positions (no check, no immediately winning capture; 6,699 with an imbalance) gives piece values of knight 2.94, bishop 2.92, rook 4.56 and queen 10.05 pawns, with the bishop pair worth 0.29 (R² 0.446). Kaufman (1999) found 3¼, 3¼, 5, 9¾ and ½ from master games.


Among positions with equal material, the features most correlated with the evaluation are centre control and piece activity in the opening (Spearman ρ 0.51 and 0.49), fading by the endgame. Doubled and isolated pawns become negative from the middlegame on. Best moves are quiet (no capture or check) in most positions of every phase. When a recapture is available it is the best move 74% of the time in middlegames. The median gap between the engine's first and second choices is under 15 cp, which is why loss, not exact match, is the right yardstick.
8. Limitations
- Horizon. M looks one exchange deep. Combinations, quiet tactical shots and long-term plans are outside the formula by design.
- Distribution. Training positions come from engine self-play. The Carlsen-game test checks transfer to human play, but not to the positions beginners reach, which are more tactical.
- Candidate generation is not modelled. The formula ranks moves. It does not find them. The candidate-list results assume the best move is on the list.
- Labels. Depth-14 MultiPV labels are noisy at the level of a few centipawns (Section 2).
- No human trial yet. We have not shown that training with the formula raises anyone's rating. The next study is a pre-registered comparison against an active control group (the same hours of ordinary puzzles), measuring blunder rate in subsequent rated games. Results will be published whatever they show, and any change to the weights will be released as a new numbered version.
9. Reproducibility
The pipeline is a set of Python scripts (python-chess, NumPy, SciPy) with fixed random seeds: sampling, Stockfish labelling, feature extraction, selection and fitting, evaluation, failure analysis and the book build. The site's calculator is a TypeScript port of the same definitions. On 12,332 moves from 400 random positions it returned identical values for all six terms. Researchers can request the code and labelled data from sigmoidvedantatechnologies@gmail.com.
References
- Shannon, C. E. (1950). Programming a computer for playing chess. Philosophical Magazine 41(314), 256–275.
- Horowitz, I. A. & Mott-Smith, G. (1960). Point Count Chess. Simon & Schuster.
- McFadden, D. (1974). Conditional logit analysis of qualitative choice behavior. In Frontiers in Econometrics. Academic Press.
- Kaufman, L. (1999). The evaluation of material imbalances. Chess Life, March 1999.
- de Groot, A. D. (1965). Thought and Choice in Chess. Mouton.
- Chase, W. G. & Simon, H. A. (1973). Perception in chess. Cognitive Psychology 4, 55–81.
- Sala, G. & Gobet, F. (2016). Do the benefits of chess instruction transfer to academic and cognitive skills? Educational Research Review 18, 46–57.
- Stockfish developers (2026). Stockfish 19. stockfishchess.org.
- Lichess (2026). lila source: winning chances and accuracy. github.com/lichess-org/lila.
Try the formula on any position, drill it daily, or get the book with 100 annotated positions.
CalculatorThe book