LovecaSim / engine /tests /scenarios /test_qa_verifications.py
trioskosmos's picture
Upload folder using huggingface_hub
bb3fbf9 verified
import numpy as np
import pytest
from engine.game.enums import Phase
from engine.game.game_state import GameState
from engine.models.ability import (
Ability,
Condition,
ConditionType,
Effect,
EffectType,
TargetType,
TriggerType,
)
from engine.models.card import MemberCard
@pytest.fixture
def state():
gs = GameState()
# Mock databases
GameState.member_db = {}
GameState.live_db = {}
return gs
def test_q171_live_end_expiry(state):
"""
Q171 Verification:
Ruling: "Until end of live" effects expire at the end of Live Result phase.
"""
p0 = state.players[0]
# 1. Apply a "until end of live" effect (e.g., +1 score bonus)
# Note: BOOST_SCORE is usually handled in live result if it has UNTIL=LIVE_END
effect = Effect(EffectType.BOOST_SCORE, 1, TargetType.PLAYER, params={"until": "live_end"})
p0.continuous_effects.append({"effect": effect, "expiry": "LIVE_END", "source_name": "Test Card"})
p0.live_score_bonus = 1
# 2. Advance through phases to LIVE_RESULT
state.phase = Phase.LIVE_RESULT
# 3. Complete live result and check if bonus is cleared
# This should call _finish_live_result internally
state._finish_live_result()
# Verification
assert p0.live_score_bonus == 0, "Q171 FAIL: live_score_bonus should be reset after live"
# Check if continuous effect is gone
has_live_end = any(e.get("expiry") == "LIVE_END" for e in p0.continuous_effects)
assert not has_live_end, "Q171 FAIL: LIVE_END continuous effects should be cleared"
def test_q129_cost_reduction_in_hand(state):
"""
Q129 Verification:
Ruling: Cost-reducing constant abilities on cards in hand MUST be accounted for.
Card: LL-bp2-001-R+ (Cost 10, reduced by 1 for each other card in hand)
"""
p0 = state.players[0]
# Ability: [常時]手札にあるこのメンバーカードのコストは、このカード以外の自分の手札1枚につき、1少なくなる。
# This is a bit tricky to mock because the engine currently doesn't have a specific Hook for 'in hand constant'
# But Q129 says it SHOULD work.
# Setup card with cost 10
# Define the cost reduction ability
cond = Condition(
ConditionType.COUNT_HAND, params={"min": 0}
) # Logic check handled by effect param `per_hand_other`
# NOTE: The engine fix looks for REDUCE_COST and then checks conditions.
# The condition "1 for each other card" is usually implemented as a multiplier.
eff = Effect(EffectType.REDUCE_COST, 1, TargetType.SELF, params={"multiplier": True, "per_hand_other": True})
ability = Ability(raw_text="Test Ability", trigger=TriggerType.CONSTANT, effects=[eff], conditions=[cond])
special_card = MemberCard(
card_id=100,
card_no="LL-bp2-001-R+",
name="渡辺 曜&...",
cost=10,
hearts=np.zeros(6),
blade_hearts=np.zeros(7),
blades=0,
abilities=[ability],
)
state.member_db[100] = special_card
# Add to hand with 4 other cards (total 5 cards)
p0.hand = [100, 101, 102, 103, 104]
# Current Engine check: get_member_cost
effective_cost = p0.get_member_cost(100, state.member_db)
# According to Q129, with 5 cards (4 other), cost should be 10 - 4 = 6.
assert effective_cost == 6, f"Q129 FAIL: Effective cost should be 6 with 4 other cards, but got {effective_cost}"