feat(gems): add multiplayer gem game with custom content packs
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
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
This commit was merged in pull request #43.
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
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
|
||||
Reference in New Issue
Block a user