Skip to main content

Automatic detection of chess tactical themes in PGN games

Project description

chess_detect

Automatic detection of chess tactical and strategic themes in PGN games using python-chess.

Analyzes PGN files and annotates moves with tactical motifs (forks, pins, skewers, discovered checks) and strategic patterns (open files, doubled/isolated pawns). Supports Russian and English output with visual PGN arrow annotations.

Документация на русском

Installation

pip install chess-detect

For development:

git clone https://github.com/aslyamov/chess_detect.git
cd chess_detect
pip install -e ".[dev]"

Quick Start

from chess_detect import ChessDetector

detector = ChessDetector(lang="en")  # or lang="ru"

pgn = """[FEN "q3k3/8/8/1N6/8/8/8/4K3 w - - 0 1"]

1. Nc7+"""

result = detector.analyze(pgn)
print(result)
# 1. Nc7+ {Fork (Nc7 -> Qa8, Ke8)} *

Tactical Themes

1. Double Check

Two pieces check the king simultaneously. The king must move.

FEN: 3k4/8/8/8/3N4/8/8/3RK3 w - - 0 1
Move: Nc6+ — knight gives check and discovers check from rook d1.

2. Fork

One piece attacks two or more valuable enemy pieces.

FEN: q3k3/8/8/1N6/8/8/8/4K3 w - - 0 1
Move: Nc7+ — knight attacks both king e8 and queen a8.

3. Discovered Check

A piece moves away, uncovering check from another piece, while making a useful attack.

FEN: 3k4/8/4p3/8/3N4/8/8/3RK3 w - - 0 1
Move: Nxe6 — knight captures pawn and discovers check from rook d1.

4. Pin

A ray piece attacks through an enemy piece to a more valuable one behind it. The front piece cannot move.

FEN: 6k1/8/4n3/8/8/1B6/8/4K3 w - - 0 1
Move: Bc4 — bishop pins knight e6 to king g8 along the diagonal.

5. Skewer

Reverse pin: the more valuable piece is in front and must move, exposing the piece behind.

FEN: 4q3/8/8/4k3/8/8/8/R5K1 w - - 0 1
Move: Re1+ — rook checks king e5, queen e8 is behind.

6. Trapped Piece

After a move, an enemy piece has no safe squares.

FEN: 4k2n/4P3/5R2/5BP1/8/8/8/4K2Q w - - 0 1
Move: g6 — knight h8 is trapped, all escape squares are under attack.

7. Hanging Capture

Capturing a piece that is undefended or can be taken by a cheaper piece.

FEN: 4k3/8/8/R3n3/8/8/8/4K3 w - - 0 1
Move: Rxe5 — rook captures undefended knight.

8. Removing Defender (material)

Capturing a piece that defended another. The defended piece is now hanging.

FEN: 4k3/8/8/8/4b3/Q1n5/8/1B2K3 w - - 0 1
Move: Qxc3 — queen takes knight that defended bishop e4.

9. Removing Defender (mate)

Capturing a piece that defended a key square. A mate threat appears.

FEN: 7k/6p1/6r1/8/4B3/2Q5/8/4K3 w - - 0 1
Move: Bxg6 — bishop takes rook, creating mate threat Qc8#.

10. Exploiting Pin

Attacking a pinned piece (it cannot escape) or capturing through a pinned defender.

FEN: 4k3/8/8/5p2/4n3/8/3P4/4R1K1 w - - 0 1
Move: d3 — pawn attacks knight e4 pinned to king by rook e1.

Strategic Motifs

Strategic themes are annotated with blue arrows/highlights (tactical themes use green). Each motif is detected once when it first appears, then ignored.

11. Open File

A file with no pawns of either color.

FEN: 4k3/8/8/3p4/8/8/8/3RK3 w - - 0 1
Move: Rxd5 — last pawn removed from d-file, the file is now open.

12. Doubled Pawns

Two or more pawns of the same color on the same file.

FEN: 4k3/8/8/8/8/3n4/2PP4/4K3 w - - 0 1
Move: cxd3 — pawn captures, creating doubled pawns on d2 and d3.

13. Isolated Pawn

A pawn with no friendly pawns on adjacent files.

FEN: 4k3/8/8/8/r1PP4/8/8/4K3 b - - 0 1
Move: Rxc4 — rook captures c4 pawn, leaving d4 pawn isolated.

Status

Theme Russian English Status
Double Check Двойной шах Double Check :white_check_mark:
Fork Вилка Fork :white_check_mark:
Discovered Check Вскрытый шах Discovered Check :white_check_mark:
Pin Связка Pin :white_check_mark:
Skewer Копьё Skewer :white_check_mark:
Trapped Piece Пойманная фигура Trapped Piece :white_check_mark:
Hanging Capture Взятие висящей фигуры Hanging Capture :white_check_mark:
Removing Defender (material) Уничтожение защитника (выигрыш фигуры) Removing Defender (winning material) :white_check_mark:
Removing Defender (mate) Уничтожение защитника (угроза мата) Removing Defender (mate threat) :white_check_mark:
Exploiting Pin Использование связки Exploiting Pin :white_check_mark:
Open File Открытая линия Open File :white_check_mark:
Doubled Pawns Сдвоенные пешки Doubled Pawns :white_check_mark:
Isolated Pawn Изолированная пешка Isolated Pawn :white_check_mark:

Planned

  • Deflection
  • Decoy
  • Zwischenzug
  • Discovered Attack
  • Back Rank Mate
  • Smothered Mate

PGN Annotations

Detected themes are visualized with arrows ([%cal]) and square highlights ([%csl]) in the PGN output. These annotations are displayed by Lichess, chess.com, and other viewers.

  • Green arrows/highlights — tactical themes
  • Blue arrows/highlights — strategic motifs
1. Nc7+ { [%csl Ga8,Ge8][%cal Gc7a8,Gc7e8] Fork (Nc7 -> Qa8, Ke8) }
1. Rxd5 { [%cal Bd1d8] Open File (d) }

Architecture

chess_detect/
├── __init__.py          # Exports ChessDetector
├── detector.py          # Main class
├── context.py           # MoveContext — lazy evaluation
├── utils.py             # Utilities (piece values, ray casting)
├── i18n/                # Translations
│   ├── ru.py
│   └── en.py
└── detectors/
    ├── base.py          # BaseDetector (arrow_color, reset)
    ├── tactics/         # 10 tactical detectors
    │   ├── double_check.py
    │   ├── fork.py
    │   ├── discovered_check.py
    │   ├── pin.py
    │   ├── skewer.py
    │   ├── trapped.py
    │   ├── hanging_capture.py
    │   ├── removing_defender.py
    │   └── exploiting_pin.py
    └── strategic/       # 3 strategic detectors
        ├── open_file.py
        ├── doubled_pawns.py
        └── isolated_pawn.py

Adding a New Detector

from ..base import BaseDetector
from ...context import MoveContext

class MyDetector(BaseDetector):
    key = "my_theme"       # i18n key
    arrow_color = "green"  # "green" for tactics, "blue" for strategy

    def detect(self, ctx: MoveContext) -> bool:
        # ctx.board_before, ctx.board_after, ctx.move
        # ctx.is_check, ctx.is_capture, ctx.captured_piece
        return False

    def format_details(self, ctx: MoveContext, lang: str) -> str:
        return ""  # e.g. "Nc7 -> Qa8, Ke8"

    def get_arrows(self, ctx: MoveContext) -> list[tuple[int, int]]:
        return []  # (from_sq, to_sq) or (sq, sq) for highlights
  1. Create a file in detectors/tactics/ or detectors/strategic/
  2. Add translations to i18n/ru.py and i18n/en.py
  3. Register in detector.py

Tests

python -m pytest tests/ -v

110 tests — all passing.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

chess_detect-0.2.0.tar.gz (38.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

chess_detect-0.2.0-py3-none-any.whl (34.5 kB view details)

Uploaded Python 3

File details

Details for the file chess_detect-0.2.0.tar.gz.

File metadata

  • Download URL: chess_detect-0.2.0.tar.gz
  • Upload date:
  • Size: 38.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for chess_detect-0.2.0.tar.gz
Algorithm Hash digest
SHA256 565f54f8a970996051054b281c97b1824341cbbc4dbbf6e4a931815c11b56946
MD5 e3ffa786a85491678541b7a0042b9c6e
BLAKE2b-256 645d783c0e22d5e0c4ff769254e9cd437ecc5ab64cdf400d3cbb4cdf4a883188

See more details on using hashes here.

Provenance

The following attestation bundles were made for chess_detect-0.2.0.tar.gz:

Publisher: publish.yml on aslyamov/chess_detect

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file chess_detect-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: chess_detect-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 34.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for chess_detect-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 35c10254f57c8b9998feae453723e8c8b59928cf6781710a0820d8f2d0e0ff3f
MD5 27df22679a10287276f40b6e27f70857
BLAKE2b-256 9e10f30437384a3ac18fb2e7459f7e5a69e921ffe6400f501f01a6c95c953a4d

See more details on using hashes here.

Provenance

The following attestation bundles were made for chess_detect-0.2.0-py3-none-any.whl:

Publisher: publish.yml on aslyamov/chess_detect

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page