Spaces:
Running
Running
| import numpy as np | |
| import pytest | |
| from engine.game.enums import Phase | |
| from engine.game.game_state import GameState | |
| from engine.models.ability import TriggerType | |
| from engine.models.card import LiveCard | |
| def game(): | |
| # Setup a game with some live cards | |
| gs = GameState() | |
| # Mock some live cards | |
| l1 = LiveCard(card_id=1001, name="Live 1", score=1, required_hearts=np.zeros(7, dtype=np.int32), card_no="L1") | |
| l2 = LiveCard(card_id=1002, name="Live 2", score=2, required_hearts=np.zeros(7, dtype=np.int32), card_no="L2") | |
| GameState.initialize_class_db({}, {1001: l1, 1002: l2}) | |
| # Setup players with live cards in passed_lives (as if performance phase finished) | |
| gs.phase = Phase.LIVE_RESULT | |
| return gs | |
| def test_tie_one_card_each(game): | |
| """Rule 8.4.6.2: Both win. Rule 8.4.7.2: Each moves 1 card.""" | |
| game.players[0].passed_lives = [1001] | |
| game.players[1].passed_lives = [1001] | |
| # Run judgment | |
| game._do_live_result() | |
| assert game.players[0].score == 1 | |
| assert game.players[1].score == 1 | |
| assert len(game.players[0].success_lives) == 1 | |
| assert len(game.players[1].success_lives) == 1 | |
| def test_tie_two_vs_one_penalty(game): | |
| """Rule 8.4.7.1: P0 has 2 cards and ties, so moves 0 cards. P1 has 1 card and moves it.""" | |
| game.players[0].passed_lives = [1001, 1001] # Total score 2 | |
| game.players[1].passed_lives = [1002] # Total score 2 | |
| game._do_live_result() | |
| # P0 tied with 2 cards -> 0 points (Rule 8.4.7.1) | |
| assert game.players[0].score == 0 | |
| # P1 tied with 1 card -> 1 point (Rule 8.4.7.2) | |
| assert game.players[1].score == 1 | |
| # P0's cards should be discarded | |
| assert len(game.players[0].passed_lives) == 0 | |
| assert 1001 in game.players[0].discard | |
| def test_win_with_multiple_cards(game): | |
| """Rule 8.4.7.3: Winning with multiple cards requires selection, yields 1 point.""" | |
| game.players[0].passed_lives = [1001, 1001] # Total score 2 | |
| game.players[1].passed_lives = [1001] # Total score 1 | |
| game._do_live_result() | |
| # Should have a pending choice to select which card moves to success_lives | |
| assert len(game.pending_choices) == 1 | |
| # Advance choice | |
| # _handle_choice will pop from game.pending_choices | |
| print(f"DEBUG: Calling _handle_choice(600) with choices: {game.pending_choices}") | |
| game._handle_choice(600) | |
| # Choices are handled during _do_live_result. | |
| # If a choice was pending, it returned early. | |
| # In a real game, _handle_choice would trigger the next step. | |
| # Since we are testing _do_live_result logic specifically: | |
| game._finish_live_result() | |
| assert game.players[0].score == 1 | |
| assert game.players[1].score == 0 | |
| def test_on_live_success_trigger_only_for_winners(game): | |
| """Rule 8.4.6: Triggers only for winners.""" | |
| from engine.models.ability import Ability | |
| # Mock member with ON_LIVE_SUCCESS | |
| abi = Ability(raw_text="Test Success", trigger=TriggerType.ON_LIVE_SUCCESS, effects=[]) | |
| from engine.models.card import MemberCard | |
| m1 = MemberCard( | |
| card_id=1, | |
| card_no="M1", | |
| name="M1", | |
| cost=1, | |
| hearts=np.zeros(7), | |
| blade_hearts=np.zeros(7), | |
| blades=1, | |
| abilities=[abi], | |
| ) | |
| GameState.initialize_class_db({1: m1}, GameState.live_db) | |
| game.players[0].stage[0] = 1 | |
| game.players[1].stage[0] = 1 | |
| # P0 wins | |
| game.players[0].passed_lives = [1002] | |
| game.players[1].passed_lives = [1001] | |
| game._do_live_result() | |
| # Only P0's trigger should be queued | |
| assert len(game.triggered_abilities) == 1 | |
| assert game.triggered_abilities[0][0] == 0 # Player 0 | |