File size: 1,421 Bytes
b5d6b93 7d4ae63 b5d6b93 7d4ae63 b5d6b93 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | """
game/deck.py — the curated duel deck (cards with real ground truth).
Phase-1 deck reuses the bundled validated example photos; each card's truth tier
is resolved from the same SPECIES_METADATA the live pipeline uses, so the game and
the model are graded against one source of truth. Grow the deck by dropping more
labelled images in examples/ and adding rows to deck.json.
"""
import json
import os
import random
from pipeline.metadata import SPECIES_METADATA, UNKNOWN_META
_HERE = os.path.dirname(__file__)
_IMAGES_DIR = os.path.join(_HERE, "deck_images")
def _load_deck() -> list[dict]:
with open(os.path.join(_HERE, "deck.json")) as f:
raw = json.load(f)
deck = []
for c in raw:
path = os.path.join(_IMAGES_DIR, c["file"])
if not os.path.exists(path):
continue
meta = SPECIES_METADATA.get(c["species"], UNKNOWN_META)
deck.append({
"file": c["file"],
"path": path,
"species": c["species"],
"tier": meta["safety"], # SAFE | CAUTION | DEADLY
"scientific": meta["scientific"],
})
return deck
DECK = _load_deck()
def random_card(exclude_file: str | None = None) -> dict:
"""Return a random card; avoid repeating the immediately-previous one when possible."""
pool = [c for c in DECK if c["file"] != exclude_file] or DECK
return random.choice(pool)
|