Files
Richie add7a6a848
treefmt / nix fmt (pull_request) Successful in 6s
test ebook search / test-ebook-search (pull_request) Successful in 39s
pytest / pytest (pull_request) Successful in 40s
build_systems / build-brain (pull_request) Successful in 1m0s
build_systems / build-bob (pull_request) Successful in 1m2s
build_systems / build-rhapsody-in-green (pull_request) Successful in 1m33s
build_systems / build-jeeves (pull_request) Successful in 2m25s
test ebook search / test-ebook-search (push) Successful in 35s
build_systems / build-brain (push) Successful in 37s
build_systems / build-bob (push) Successful in 37s
build_systems / build-jeeves (push) Successful in 2m17s
treefmt / nix fmt (push) Successful in 5s
pytest / pytest (push) Successful in 29s
build_systems / build-rhapsody-in-green (push) Successful in 49s
feat(gems): add multiplayer gem game with custom content packs
- implement FastAPI and HTMX lobby and game interfaces
- support up to four human and AI-controlled players
- add configurable rules, victory conditions, and expansion modules
- support validated JSON cards, patrons, objectives, and outposts
2026-07-22 20:47:03 -04:00

77 lines
3.1 KiB
Python

"""Synthetic content builders; no playable pack is bundled with the app."""
from __future__ import annotations
import pytest
from python.gems.domain.models import (
AlternateCost,
CardDefinition,
CardEffect,
CardEffectKind,
ContentPack,
ObjectiveDefinition,
OutpostDefinition,
OutpostPower,
PackMetadata,
PatronDefinition,
Requirement,
RequirementKind,
ResourceDefinition,
)
@pytest.fixture
def content_pack() -> ContentPack:
resources = [
ResourceDefinition(id=name, label=name.title(), symbol=str(index + 1), color=f"#{index + 2}{index + 2}4455")
for index, name in enumerate(("pearl", "wave", "leaf", "flame", "stone"))
]
cards = []
for deck in ("base", "eastern"):
for tier in (1, 2, 3):
for index, resource in enumerate(resources):
effect = CardEffect()
if deck == "eastern" and tier == 1 and index == 0:
effect = CardEffect(kind=CardEffectKind.VIRTUAL_WILD, amount=2)
if deck == "eastern" and tier == 1 and index == 1:
effect = CardEffect(kind=CardEffectKind.COPY_BONUS)
if deck == "eastern" and tier == 2 and index == 0:
effect = CardEffect(kind=CardEffectKind.COPY_AND_CLAIM, target_tier=1)
if deck == "eastern" and tier == 2 and index == 1:
effect = CardEffect(kind=CardEffectKind.MULTI_BONUS, amount=2)
if deck == "eastern" and tier == 3 and index == 0:
effect = CardEffect(kind=CardEffectKind.CLAIM_FREE, target_tier=2)
alternate = (
AlternateCost(discard_resource="stone", count=2)
if deck == "eastern" and tier == 3 and index == 1
else None
)
cards.append(
CardDefinition(
id=f"{deck}_{tier}_{index}",
label=f"{deck.title()} {tier}-{index}",
deck=deck,
tier=tier,
points=tier - 1,
bonus_resource=resource.id,
cost={resources[(index + 1) % 5].id: tier},
effect=effect,
alternate_cost=alternate,
)
)
requirement = Requirement(id="need_pearl", kind=RequirementKind.COLOR, resource="pearl", count=1)
return ContentPack(
schema_version=1,
metadata=PackMetadata(id="synthetic", name="Synthetic Tests", version="1"),
resources=resources,
wild_resource=ResourceDefinition(id="wild", label="Wild", symbol="*", color="#aaaaaa"),
cards=cards,
patrons=[PatronDefinition(id="patron_one", label="Patron One", points=3, requirements=[requirement])],
objectives=[ObjectiveDefinition(id="goal_one", label="Goal One", minimum_score=0, requirements=[requirement])],
outposts=[
OutpostDefinition(id=f"post_{power.value}", label=power.value, requirements=[requirement], power=power)
for power in OutpostPower
],
)