File size: 2,961 Bytes
6bbf552
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import pytest

from primitives import Effect, get_primitive, primitive_allowed_for_school, primitive_ids, render_effect, school_bias, school_primitives


# Verify the fixed primitive vocabulary stays complete.
def test_primitive_ids_are_the_locked_thirteen() -> None:
    assert primitive_ids() == (
        "deal",
        "burn",
        "bomb",
        "block",
        "ward",
        "weak",
        "draw",
        "energy",
        "initiative",
        "multi_hit",
        "vulnerable",
        "conditional",
        "scaling",
    )


# Verify school draft pools match the README.
def test_school_primitives_match_spec() -> None:
    assert school_primitives("fire") == ("deal", "burn", "bomb", "scaling", "draw", "energy", "block", "conditional")
    assert school_primitives("ice") == ("deal", "initiative", "vulnerable", "multi_hit", "conditional", "draw", "energy", "block")
    assert school_primitives("earth") == ("deal", "ward", "block", "weak", "scaling", "conditional", "draw", "energy")
    assert primitive_allowed_for_school("deal", "fire")
    assert primitive_allowed_for_school("deal", "ice")
    assert not primitive_allowed_for_school("bomb", "ice")


# Verify school bias explains generation weights.
def test_school_bias() -> None:
    assert "immediate Deal" in school_bias("fire")
    assert "shield charge" in school_bias("earth")


# Verify primitive lookup returns the stored schema.
def test_get_primitive_returns_spec() -> None:
    primitive = get_primitive("ward")
    assert primitive.name == "Ward"
    assert primitive.category == "defense"


@pytest.mark.parametrize(
    ("effect", "text"),
    (
        (Effect("deal", amount=4), "Deal 4 damage."),
        (Effect("burn", amount=2, duration=3), "Burn 2 damage for 3 turns."),
        (Effect("bomb", amount=9, delay=3), "Bomb: deal 9 damage in 3 turns."),
        (Effect("block", amount=6), "Gain 6 block until your next turn."),
        (Effect("ward", amount=2), "Gain 2 ward."),
        (Effect("weak", amount=2), "Opponent deals 2 less damage until your next turn."),
        (Effect("draw", amount=1), "Draw 1 card."),
        (Effect("draw", amount=2), "Draw 2 cards."),
        (Effect("energy", amount=1), "Gain 1 energy this turn."),
        (Effect("initiative"), "Opponent acts second next round."),
        (Effect("multi_hit", amount=2, hits=3), "Deal 2 damage 3 times."),
        (Effect("vulnerable", amount=1, duration=2), "Opponent takes 1 more damage for 2 turns."),
        (Effect("conditional", amount=6), "Deal up to 6 damage based on opponent's missing HP."),
        (Effect("scaling", amount=2), "Deal 2 damage plus cards played this turn."),
        (Effect("scaling", amount=2, condition="shield_charge"), "Deal 2 damage plus your banked shield charge, then empty it."),
    ),
)
# Verify every effect renders to fixed parseable text.
def test_render_effect(effect: Effect, text: str) -> None:
    assert render_effect(effect) == text