CLI tool that fetches your recent chess.com or Lichess games, analyzes every move with Stockfish, and surfaces recurring positions where you consistently lose the most centipawns — revealing your most costly habits.
- Python 3.10+
- Stockfish installed and accessible
- Ubuntu/Debian:
sudo apt install stockfish - macOS:
brew install stockfish - Or set the
STOCKFISH_PATHenvironment variable to point to your binary
- Ubuntu/Debian:
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txtpython3 chess_tutor.py <username> [options]| Flag | Default | Description |
|---|---|---|
-p, --platform |
chess.com |
Platform to fetch games from (chess.com or lichess) |
-n, --top |
20 | Number of results to display |
-c, --min-count |
10 | Minimum times a position must recur |
-l, --min-cploss |
0 | Minimum centipawn loss to include a position |
-m, --months |
2 | How many months to look back |
-d, --depth |
16 | Stockfish search depth |
-s, --side |
both | Filter by white or black |
-t, --time-control |
all | Filter by time class: rapid, blitz, bullet, daily |
-h, --help |
Show help message and exit |
# Default — last 2 months, all games, top 20 positions (chess.com)
python3 chess_tutor.py USERNAME
# Analyze Lichess games
python3 chess_tutor.py USERNAME -p lichess
# Top 10 blitz positions as white over the last 4 months at depth 20
python3 chess_tutor.py USERNAME -n 10 -m 4 -d 20 -s white -t blitz
# Lichess rapid games from the last 3 months
python3 chess_tutor.py USERNAME -p lichess -m 3 -t rapid
# Positions that recur at least 5 times with at least 50cp loss
python3 chess_tutor.py USERNAME -c 5 -l 50
# Show help
python3 chess_tutor.py -h========================================================================================================================================================================
Top 20 Recurring Positions by Total Centipawn Impact
========================================================================================================================================================================
# Side Count CpLoss Impact Played Best
--- ---- ----- ------ ------- ------------------------------------------------------------------ ------------------------------------------------------------------
1 W 14 35 490 b4 (Italian Game: Evans Gambit) d3 (Italian Game: Giuoco Pianissimo)
2 W 12 19 228 Nf3 (French Defense: Knight Variation) d4 (French Defense: Normal Variation)
3 B 11 19 209 c5 (Caro-Kann Defense: Advance Variation, Botvinnik-Carls Defense) Bf5 (Caro-Kann Defense: Advance Variation + Bf5)
4 W 16 12 192 Ng5 (Italian Game: Two Knights Defense, Knight Attack) d3 (Italian Game: Two Knights Defense, Modern Bishop's Opening)
5 W 45 2 90 Bc4 (Italian Game) Bb5 (Ruy Lopez)
6 B 26 2 52 Nf6 (Indian Defense) d5 (Queen's Pawn Game)
The Played and Best columns are terminal hyperlinks — click them to open the position on the platform's analysis board (chess.com or Lichess).
- Centipawn loss: the drop in engine evaluation caused by your move (engine eval before minus eval after). Higher means a worse move.
- Impact:
centipawn_loss × count. Positions you visit often with a bad move rank highest, so you focus on what costs you the most games. - Identical positions (same FEN + same move) are analyzed by Stockfish only once; subsequent occurrences increment the count.
- Positions are matched using normalized FEN (first 4 fields only), so transpositions reaching the same position are correctly grouped.
The tool labels positions with opening names using a local openings.json file. To generate or update it from the Lichess ECO database:
python3 generate_openings.pyWhen a position falls outside known book lines, the tool labels it based on the last known opening plus the subsequent moves (e.g., "Sicilian Defense + Bc4 d6 Nf3").
Game data and Stockfish analysis results are cached in a .cache/ directory next to the script:
- Game cache: completed months are cached permanently; the current month is always re-fetched to pick up new games. Filtering by side or time control happens downstream, so the cache always stores all games for a month.
- Analysis cache: per-position Stockfish evaluations are cached per depth (e.g.,
analysis_d16.json,analysis_d20.json), so changing--depthdoesn't invalidate existing results.
To force a fresh analysis, delete the .cache/ directory.