File size: 6,715 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
173
174
import numpy as np
import pytest

from engine.game.enums import Phase
from engine.game.game_state import GameState, LiveCard, MemberCard


class TestPerformanceResults:
    @pytest.fixture(autouse=True)
    def setup(self):
        self.game = GameState(verbose=True)
        self.p0 = self.game.players[0]

        # Setup mock databases
        self.game.member_db[1] = MemberCard(
            card_id=1,
            card_no="M1",
            name="Member 1",
            cost=1,
            hearts=np.array([1, 0, 0, 0, 0, 0, 0]),
            blade_hearts=np.array([0, 1, 0, 0, 0, 0, 0]),
            blades=1,
            abilities=[],
            img_path="m1.png",
        )
        self.game.live_db[100] = LiveCard(
            card_id=100,
            card_no="L1",
            name="Live 1",
            score=1,
            required_hearts=np.array([1, 1, 0, 0, 0, 0, 0]),
            abilities=[],
            img_path="l1.png",
        )

    def test_performance_results_population(self):
        """Verify that _do_performance populates performance_results correctly."""
        # 1. Setup Stage & Live Zone
        self.p0.stage[0] = 1  # Member 1 in Area 0
        self.p0.live_zone = [100]  # Live 1 in Live Zone

        # 2. Setup Yell Card (Member 1 also used as yell)
        # This will provide 1 Red Blade Heart.
        # Member 1 in stage provides 1 Pink Heart.
        # Total: 1 Pink, 1 Red. Requirement for Live 1: 1 Pink, 1 Red.
        self.p0.main_deck = [1]

        # 3. Trigger Performance Phase 1
        self.game.phase = Phase.PERFORMANCE_P1
        self.game.current_player = 0

        # Manually call _do_performance
        self.game._do_performance(0)

        # 4. Verify results
        assert 0 in self.game.performance_results
        res = self.game.performance_results[0]

        assert res["success"] is True
        assert len(res["member_contributions"]) == 1
        assert res["member_contributions"][0]["id"] == 1
        # Expect 7 elements for hearts (6 colors + Any/Star)
        assert res["member_contributions"][0]["hearts"] == [1, 0, 0, 0, 0, 0, 0]

        assert len(res["yell_cards"]) == 1
        assert res["yell_cards"][0]["id"] == 1
        assert res["yell_cards"][0]["blade_hearts"] == [0, 1, 0, 0, 0, 0, 0]

        # Total hearts should be [1, 1, 0, 0, 0, 0, 0] (Pink, Red, ...)
        assert res["total_hearts"] == [1, 1, 0, 0, 0, 0, 0]

        assert len(res["lives"]) == 1
        assert res["lives"][0]["id"] == 100
        assert res["lives"][0]["passed"] == True
        assert res["lives"][0]["score"] == 1

    def test_performance_results_cleared_on_reset(self):
        """Verify that performance_results are cleared on game reset."""
        self.game.performance_results[0] = {"dummy": "data"}
        self.game._reset()
        assert not self.game.performance_results

    def test_mixed_performance_results(self):
        """Verify that multiple lives track individual pass/fail status and scoring correctly."""
        # Setup: Live 1 (ID 100) needs Pink+Red. Live 2 (ID 101) needs 2 Pink.
        self.game.live_db[101] = LiveCard(
            card_id=101,
            card_no="L2",
            name="Live 2",
            score=2,
            required_hearts=np.array([2, 0, 0, 0, 0, 0, 0]),
            abilities=[],
            img_path="l2.png",
        )

        # Player has 1 Pink (Member 1) and 1 Red (Yell).
        # Live 1 (index 0) needs 1 Pink, 1 Red -> PASSED.
        # Live 2 (index 1) needs 2 Pink -> FAILED (only 0 Pink remain after consumption).

        self.p0.stage[0] = 1  # Member 1
        self.p0.live_zone = [100, 101]
        self.p0.main_deck = [1]  # For yell

        self.game.phase = Phase.PERFORMANCE_P1
        self.game.current_player = 0
        self.game._do_performance(0)

        res = self.game.performance_results[0]
        assert res["success"] is False  # Overall success is false because not all met
        assert len(res["lives"]) == 2

        # Live 1 should be passed
        assert res["lives"][0]["id"] == 100
        assert res["lives"][0]["passed"] is True

        # Live 2 should be failed
        assert res["lives"][1]["id"] == 101
        assert res["lives"][1]["passed"] is False

        # Score calculation in LiveResult phase
        self.game.phase = Phase.LIVE_RESULT
        self.game._do_live_result()

        # Rule 8.4.7: Because Live 2 failed, the entire performance failed (Rule 8.3.16).
        # Score should be 0.
        assert self.p0.score == 0

    def test_tie_penalty(self):
        """Verify Rule 8.4.7.1: Tie with 2+ cards results in 0 points."""
        # Setup: P0 and P1 both perform 2 lives successfully.
        p0, p1 = self.game.players[0], self.game.players[1]
        self.game.live_db[102] = LiveCard(
            card_id=102, card_no="L3", name="L3", score=1, required_hearts=np.array([0] * 7), abilities=[], img_path=""
        )
        self.game.live_db[103] = LiveCard(
            card_id=103, card_no="L4", name="L4", score=1, required_hearts=np.array([0] * 7), abilities=[], img_path=""
        )

        p0.passed_lives = [100, 102]
        p1.passed_lives = [101, 103]

        # Scoring: Both have 2 points (Live 1 + Live 3 vs Live 2 + Live 4)
        # Note: I'm manually Setting passed_lives to skip _do_performance heart checks

        self.game.phase = Phase.LIVE_RESULT
        self.game._do_live_result()

        # Both tied with 2+ cards -> should get 0 points
        assert p0.score == 0
        assert p1.score == 0
        assert len(p0.success_lives) == 0
        assert len(p1.success_lives) == 0

    def test_interactive_selection_choice(self):
        """Verify Rule 8.4.7.3: Multiple successful lives create a SELECT_SUCCESS_LIVE choice."""
        # Setup: P0 performs 2 lives, P1 performs 0.
        p0 = self.game.players[0]
        self.game.live_db[102] = LiveCard(
            card_id=102, card_no="L3", name="L3", score=1, required_hearts=np.array([0] * 7), abilities=[], img_path=""
        )

        p0.passed_lives = [100, 102]
        self.game.players[1].passed_lives = []

        self.game.phase = Phase.LIVE_RESULT
        self.game._do_live_result()

        # P0 wins but has 2 cards -> choice pending
        assert len(self.game.pending_choices) == 1
        assert self.game.pending_choices[0][0] == "SELECT_SUCCESS_LIVE"
        assert self.game.pending_choices[0][1]["player_id"] == 0
        assert self.game.pending_choices[0][1]["cards"] == [100, 102]
        assert self.game.current_player == 0