File size: 5,945 Bytes
bb3fbf9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
"""

Auto-generates test cases for all cards with abilities.

"""

import json
from pathlib import Path
from typing import Any, Dict, List


def load_card_database() -> Dict[str, Any]:
    """Load compiled card database."""
    # Try multiple paths
    paths = [
        Path("data/cards_compiled.json"),
        Path("engine/data/cards_compiled.json"),
    ]
    for p in paths:
        if p.exists():
            with open(p, "r", encoding="utf-8") as f:
                return json.load(f)
    raise FileNotFoundError("Could not find cards_compiled.json")


def generate_ability_test_cases() -> List[Dict[str, Any]]:
    """

    Generate parametrized test cases for all cards with abilities.



    Returns list of dicts with:

    - card_id: int

    - card_name: str

    - card_type: 'member' or 'live'

    - ability_idx: int

    - trigger: str (e.g., 'ON_PLAY', 'LIVE_START')

    - effects: List[str] (e.g., ['DRAW_CARDS', 'DISCARD'])

    - has_cost: bool

    - is_optional: bool

    """
    data = load_card_database()
    test_cases = []

    # Process members
    from engine.models.ability import TriggerType

    for cid_str, card in data.get("member_db", {}).items():
        cid = int(cid_str)
        abilities = card.get("abilities", [])
        for idx, ability in enumerate(abilities):
            raw_trigger = ability.get("trigger", "NONE")
            # Map int to Enum name if possible
            try:
                if isinstance(raw_trigger, int):
                    trigger = TriggerType(raw_trigger).name
                else:
                    trigger = raw_trigger
            except Exception:
                trigger = str(raw_trigger)

            effects = [e.get("effect_type", "UNKNOWN") for e in ability.get("effects", [])]
            costs = ability.get("costs", [])
            # Map condition enums
            from engine.models.ability import ConditionType, TriggerType

            conditions = []
            for c in ability.get("conditions", []):
                # Compiled JSON uses 'type' for ConditionType
                ctype = c.get("type", c.get("condition_type", "NONE"))
                try:
                    if isinstance(ctype, int):
                        cname = ConditionType(ctype).name
                    else:
                        cname = ctype
                except Exception:
                    cname = str(ctype)

                cond_copy = c.copy()
                cond_copy["condition_type"] = cname
                conditions.append(cond_copy)

            test_cases.append(
                {
                    "card_id": cid,
                    "card_name": card.get("name", f"Unknown_{cid}"),
                    "card_type": "member",
                    "ability_idx": idx,
                    "trigger": trigger,
                    "effects": effects,
                    "conditions": conditions,
                    "has_cost": len(costs) > 0,
                    "is_optional": any(c.get("is_optional", False) for c in costs),
                    "raw_text": ability.get("raw_text", "")[:50],
                }
            )

    # Process lives
    for cid_str, card in data.get("live_db", {}).items():
        cid = int(cid_str)
        abilities = card.get("abilities", [])
        for idx, ability in enumerate(abilities):
            trigger = ability.get("trigger", "NONE")
            effects = [e.get("effect_type", "UNKNOWN") for e in ability.get("effects", [])]

            test_cases.append(
                {
                    "card_id": cid,
                    "card_name": card.get("name", f"Unknown_{cid}"),
                    "card_type": "live",
                    "ability_idx": idx,
                    "trigger": trigger,
                    "effects": effects,
                    "has_cost": False,
                    "is_optional": False,
                    "raw_text": ability.get("raw_text", "")[:50],
                }
            )

    return test_cases


def get_cards_by_trigger(trigger: str) -> List[Dict[str, Any]]:
    """Get all test cases with a specific trigger type."""
    return [tc for tc in generate_ability_test_cases() if tc["trigger"] == trigger]


def get_cards_by_effect(effect: str) -> List[Dict[str, Any]]:
    """Get all test cases that include a specific effect type."""
    return [tc for tc in generate_ability_test_cases() if effect in tc["effects"]]


def get_complex_cards(min_effects: int = 3) -> List[Dict[str, Any]]:
    """Get cards with complex abilities (multiple effects)."""
    return [tc for tc in generate_ability_test_cases() if len(tc["effects"]) >= min_effects]


def get_cards_with_condition(condition_type: str) -> List[Dict[str, Any]]:
    """Get all test cases that have a specific condition type."""
    cases = []
    for tc in generate_ability_test_cases():
        for cond in tc.get("conditions", []):
            if cond.get("condition_type") == condition_type:
                cases.append(tc)
                break
    return cases


# Summary statistics
def print_ability_summary():
    """Print summary of ability coverage."""
    cases = generate_ability_test_cases()

    # Count by trigger
    triggers = {}
    for tc in cases:
        triggers[tc["trigger"]] = triggers.get(tc["trigger"], 0) + 1

    # Count by effect
    effects = {}
    for tc in cases:
        for e in tc["effects"]:
            effects[e] = effects.get(e, 0) + 1

    print(f"Total abilities: {len(cases)}")
    print("\nBy Trigger:")
    for t, c in sorted(triggers.items(), key=lambda x: -x[1]):
        print(f"  {t}: {c}")
    print("\nBy Effect (top 15):")
    for e, c in sorted(effects.items(), key=lambda x: -x[1])[:15]:
        print(f"  {e}: {c}")


if __name__ == "__main__":
    print_ability_summary()