# chess_detect

Automatic detection of chess tactical themes in PGN games using [python-chess](https://python-chess.readthedocs.io/).

Analyzes PGN files and annotates moves with tactical motifs: forks, pins, skewers, discovered checks, and more. Supports Russian and English output with visual PGN arrow annotations.

[Документация на русском](README_RU.md)

## Installation

```bash
pip install chess-detect
```

For development:

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

## Quick Start

```python
from chess_detect import ChessDetector

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

pgn = """
1. e4 e5 2. Nf3 Nc6 3. Bb5 a6
"""

result = detector.analyze(pgn)
print(result)
# PGN with tactical annotations in comments
```

## Supported Tactics

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

### Planned

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

## PGN Arrow Annotations

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

Example output:

```
1. Nc7+ { [%csl Ga8,Ge8][%cal Gc7a8,Gc7e8] Fork (Nc7 → Qa8, Ke8) }
```

## Architecture

```
chess_detect/
├── __init__.py          # Exports ChessDetector
├── detector.py          # Main class
├── context.py           # MoveContext — lazy evaluation
├── utils.py             # Utilities (piece values, vulnerability checks)
├── i18n/                # Translations
│   ├── ru.py
│   └── en.py
└── detectors/
    ├── base.py          # BaseDetector
    └── tactics/
        ├── double_check.py
        ├── fork.py
        ├── discovered_check.py
        ├── pin.py
        ├── skewer.py
        ├── trapped.py
        ├── hanging_capture.py
        ├── removing_defender.py
        └── exploiting_pin.py
```

## Adding a New Detector

```python
from ..base import BaseDetector
from ...context import MoveContext

class MyTacticDetector(BaseDetector):
    key = "my_tactic"  # i18n key

    def detect(self, ctx: MoveContext) -> bool:
        # ctx.board_before — position before the move
        # ctx.board_after — position after the move
        # ctx.move — the move itself
        # ctx.is_check — is it check?
        # ctx.is_capture — is it a capture?
        # ctx.captured_piece — captured piece
        return False
```

1. Create a file in `detectors/tactics/`
2. Add translations to `i18n/ru.py` and `i18n/en.py`
3. Register in `detector.py`

## Tests

```bash
python -m pytest tests/ -v
```

**89 tests** — all passing.

## License

[MIT](LICENSE)
