Metadata-Version: 2.4
Name: i151-engine
Version: 0.2.0
Summary: Headless game engine for the i151 student AI competition
Requires-Python: >=3.11
Description-Content-Type: text/markdown
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"

# i151-engine

Moteur de jeu **headless** pour la [compétition IA i151](https://i151.djamma.dev) : règles du jeu de cartes, matchs bot vs bot reproductibles, replays JSON.

**Étudiants** : installez plutôt [`i151-arena-sdk`](https://pypi.org/project/i151-arena-sdk/) — ce moteur y est inclus comme dépendance, avec la CLI `arena` et les outils de soumission.

**Prérequis** : Python 3.11+

## Installation

```bash
pip install i151-engine
```

Développement (monorepo) :

```bash
pip install -e ".[dev]"
pytest
```

## Usage

```python
from i151_engine.bots.random_bot import RandomBot
from i151_engine.runner.config import MatchConfig
from i151_engine.runner.match_runner import play_match

result = play_match(
    RandomBot(),
    "builtin:random",
    MatchConfig(seed=42, target_score=151, cards_per_player=8),
)
print(result.reason, result.winner_id, result.final_scores)
```

## Fonctionnalités

| Module | Rôle |
|--------|------|
| `models/` | Cartes, actions, état joueur |
| `core/` | Règles, actions légales, réducteur, scores |
| `game/` | Manches, parties, enregistreur de replay |
| `view/` | `PlayerView` — perspective partielle pour les bots |
| `opponents/` | Catalogue d'adversaires (`builtin:random`, …) |
| `runner/` | `play_match`, timeouts, forfaits |

**v1** : 2 joueurs, partie jusqu'à 151 points, RNG seedé, un adversaire intégré actif (`builtin:random`).

## Adversaires

Les matchs référencent un `opponent_id` stable (ex. `builtin:random`). Le catalogue complet est dans `i151_engine.opponents.catalog` ; seuls les adversaires `implemented=True` sont jouables.

## Interface bot

```python
class Bot(Protocol):
    def setup(self, submission_dir: Path) -> None: ...
    def decide(self, view: PlayerView, legal_actions: list[Action], time_left_ms: int) -> Action: ...
    def teardown(self) -> None: ...
```

Les bots étudiants implémentent `decide()` via le SDK (`arena_sdk`), pas directement ce protocole.

## Documentation

| Ressource | Lien |
|-----------|------|
| SDK étudiant | [i151-arena-sdk sur PyPI](https://pypi.org/project/i151-arena-sdk/) |
| Tutoriel | [i151.djamma.dev/docs/tutorial](https://i151.djamma.dev/docs/tutorial) |
| Architecture détaillée | [i151.djamma.dev/docs/architecture](https://i151.djamma.dev/docs/architecture) |

Documentation technique interne (monorepo) : `ARCHITECTURE.md`.
