from engine.game.game_state import initialize_game def setup_test_state(): # initialize_game loads real data into GameState.member_db and live_db state = initialize_game(use_real_data=True) return state def test_PL_bp3_006_R_maki_ability_zero_success(): """ PL!-bp3-006-R (Nishikino Maki) [Live Start] Discard 1 from hand: +2 blades for each success live card until live end. Test with 0 success lives. """ state = setup_test_state() p0 = state.players[0] # Maki's Card ID is 26 in cards_compiled.json maki_id = 26 # Setup state p0.hand = [1, 2] # Two dummy cards p0.success_lives = [] # 0 success lives maki_card = state.member_db[maki_id] ability = maki_card.abilities[0] # Trigger Maki's ability. state.triggered_abilities.append((0, ability, {"card_id": maki_id, "area": 1})) # Center while state.triggered_abilities and not state.pending_choices: player_id, ab, context = state.triggered_abilities.pop(0) state._play_automatic_ability(player_id, ab, context) # Answer the choice: discard card at index 0 (ID 1) state._handle_choice(500) # Process the effect while state.pending_effects or state.triggered_abilities: state._resolve_pending_effect(0, {"card_id": maki_id, "area": 1}) # Verify blade bonus. # Python engine: ADD_BLADES with multiplier=True calculates val at resolution. # val = 2 * 0 lives = 0. # It appends a dict with "effect": Effect(ADD_BLADES, 0, ...) found_effect = False for effect_dict in p0.continuous_effects: effect = effect_dict["effect"] # EffectType.ADD_BLADES = 1 if effect.effect_type.value == 1: found_effect = True assert effect.value == 0 # Since Maki's ability usually targets self (MEMBER_SELF), # the target_slot should be the area provided in context (1). assert effect_dict["target_slot"] == 1 assert found_effect def test_PL_bp3_006_R_maki_ability_two_success(): """ Test with 2 success lives. Expect +4 blades. """ state = setup_test_state() p0 = state.players[0] maki_id = 26 # Setup state: 2 success lives p0.hand = [1, 2] p0.success_lives = [100, 101] # Two dummy success lives maki_card = state.member_db[maki_id] ability = maki_card.abilities[0] state.triggered_abilities.append((0, ability, {"card_id": maki_id, "area": 0})) # Left while state.triggered_abilities and not state.pending_choices: player_id, ab, context = state.triggered_abilities.pop(0) state._play_automatic_ability(player_id, ab, context) # Discard 1 state._handle_choice(500) while state.pending_effects or state.triggered_abilities: state._resolve_pending_effect(0, {"card_id": maki_id, "area": 0}) # Verify bonus. 2 lives * 2 blades = 4 blades. found = False for effect_dict in p0.continuous_effects: effect = effect_dict["effect"] if effect.effect_type.value == 1: found = True assert effect.value == 4 assert effect_dict["target_slot"] == 0 assert found def test_PL_bp3_006_R_maki_ability_optional_deny(): """ Test denying the optional cost. """ state = setup_test_state() p0 = state.players[0] maki_id = 26 p0.hand = [1] maki_card = state.member_db[maki_id] ability = maki_card.abilities[0] state.triggered_abilities.append((0, ability, {"card_id": maki_id, "area": 2})) # Right while state.triggered_abilities and not state.pending_choices: player_id, ab, context = state.triggered_abilities.pop(0) state._play_automatic_ability(player_id, ab, context) # Deny the choice (PASS is action 0) state._handle_choice(0) while state.pending_effects or state.triggered_abilities: state._resolve_pending_effect(0, {"card_id": maki_id, "area": 2}) # No continuous effect should be added assert len(p0.continuous_effects) == 0