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
- 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
61 lines
2.5 KiB
Python
61 lines
2.5 KiB
Python
from __future__ import annotations
|
|
|
|
from python.gems.domain.engine import bonuses, new_game
|
|
from python.gems.domain.models import GameSettings, Modules, OwnedCard, Requirement, RequirementKind, ResourceDefinition
|
|
from python.gems.domain.requirements import requirements_met
|
|
|
|
|
|
def test_any_color_requirements_can_be_distinct() -> None:
|
|
requirements = [
|
|
Requirement(id="first", kind=RequirementKind.ANY_COLOR, count=2),
|
|
Requirement(id="second", kind=RequirementKind.ANY_COLOR, count=2, distinct_from=["first"]),
|
|
]
|
|
assert requirements_met(requirements, {"pearl": 2, "wave": 2})
|
|
assert not requirements_met(requirements, {"pearl": 3, "wave": 1})
|
|
|
|
|
|
def test_light_resource_colors_use_dark_token_lettering() -> None:
|
|
light = ResourceDefinition(id="light", label="Light", symbol="W", color="#f4f2ed")
|
|
gold = ResourceDefinition(id="gold", label="Gold", symbol="Au", color="#d9a928")
|
|
dark = ResourceDefinition(id="dark", label="Dark", symbol="B", color="#151719")
|
|
assert light.ink_color == "#111111"
|
|
assert gold.ink_color == "#ffffff"
|
|
assert dark.ink_color == "#ffffff"
|
|
|
|
|
|
def test_standard_resources_store_conventional_symbols() -> None:
|
|
"""Standard gem labels normalize legacy abbreviations in pack data."""
|
|
standard = {
|
|
"Onyx": "O",
|
|
"Sapphire": "S",
|
|
"Emerald": "E",
|
|
"Ruby": "R",
|
|
"Diamond": "D",
|
|
"Gold": "G",
|
|
}
|
|
|
|
for label, expected in standard.items():
|
|
resource = ResourceDefinition(id=label.casefold(), label=label, symbol="?", color="#334455")
|
|
assert resource.symbol == expected
|
|
|
|
custom = ResourceDefinition(id="pearl", label="Pearl", symbol="P", color="#334455")
|
|
assert custom.symbol == "P"
|
|
|
|
|
|
def test_all_modules_deal_their_content(content_pack) -> None:
|
|
settings = GameSettings(modules=Modules(objectives=True, outposts=True, eastern_decks=True, fortifications=True))
|
|
state = new_game("ABCDEFGH", ["A", "B"], content_pack, settings, seed=5)
|
|
assert "eastern:1" in state.markets
|
|
assert state.available_objectives == ["goal_one"]
|
|
assert not state.available_patrons
|
|
assert state.players[0].fortifications_available == 3
|
|
|
|
|
|
def test_multi_bonus_counts_twice_but_is_one_card(content_pack) -> None:
|
|
settings = GameSettings(modules=Modules(eastern_decks=True))
|
|
state = new_game("ABCDEFGH", ["A"], content_pack, settings, seed=5)
|
|
player = state.players[0]
|
|
player.cards.append(OwnedCard(card_id="eastern_2_1"))
|
|
assert bonuses(player, content_pack)[content_pack.card("eastern_2_1").bonus_resource] == 2
|
|
assert len(player.cards) == 1
|