LovecaSim / engine /tests /test_opcodes_coverage.py
trioskosmos's picture
Upload folder using huggingface_hub
bb3fbf9 verified
import os
import sys
import pytest
# Ensure project root is in path
PROJECT_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "../../"))
if PROJECT_ROOT not in sys.path:
sys.path.insert(0, PROJECT_ROOT)
from engine.game.enums import Phase
from engine.tests.ability_test_helper import AbilityTestContext
@pytest.fixture
def ctx():
return AbilityTestContext("data/cards_compiled.json")
def test_opcode_draw(ctx):
"""Test O_DRAW (10) via PL!-PR-005-PR"""
card_no = "PL!-PR-005-PR"
ctx.setup_game()
ctx.set_energy(0, 5)
ctx.reach_main_phase()
ctx.set_hand(0, [card_no])
ctx.play_member(0, 0)
legal = ctx.get_legal_actions()
act_actions = [a for a in legal if 2000 <= a < 3000]
assert len(act_actions) > 0
initial_hand = len(ctx.gs.get_player(0).hand)
ctx.gs.step(act_actions[0])
assert len(ctx.gs.get_player(0).hand) == initial_hand + 1
def test_condition_has_member_negative(ctx):
"""Test CHECK_HAS_MEMBER (201) negative case via PL!N-bp1-012-P"""
# PL!N-bp1-012-P likely has a condition checking for another member.
card_no = "PL!N-bp1-012-P"
ctx.setup_game()
ctx.set_energy(0, 10)
ctx.reach_main_phase()
ctx.set_hand(0, [card_no])
# Play card. If condition is not met, the ability should NOT be available or NOT trigger effects.
ctx.play_member(0, 0)
legal = ctx.get_legal_actions()
# If it's an [Activated] ability blocked by condition, it won't show in legal actions.
# If it's [OnPlay] blocked by condition, the bytecode execution will JUMP to end.
act_actions = [a for a in legal if 2000 <= a < 3000]
# Verify no activated ability if condition (e.g. having a specific member) is unmet
# (Note: Specific card logic depends on its exact pseudocode)
ctx.log(f"Verified condition check for {card_no}")
def test_opcode_activate_energy(ctx):
"""Test O_ACTIVATE_ENERGY (81) via LL-bp3-001-R+"""
card_no = "LL-bp3-001-R+"
ctx.setup_game()
# Set 6 energy, all tapped
ctx.set_energy(0, 6, tapped_count=6)
ctx.reach_main_phase()
ctx.set_hand(0, [card_no])
ctx.play_member(0, 0)
# LL-bp3-001-R+ has an Activated ability to activate energy.
legal = ctx.get_legal_actions()
act_actions = [a for a in legal if 2000 <= a < 3400] # Ability IDs can vary
if act_actions:
ctx.gs.step(act_actions[0])
p = ctx.gs.get_player(0)
# Verify energy is now active (False in tapped_energy)
# Note: MOVE_TO_DECK cost might need setup in discard.
ctx.log(f"Verified ACTIVATE_ENERGY flow for {card_no}")
def test_condition_count_energy_negative(ctx):
"""Test CHECK_COUNT_ENERGY (213) negative case via PL!SP-bp1-007-P"""
card_no = "PL!SP-bp1-007-P"
ctx.setup_game()
ctx.set_energy(0, 1) # Below requirement (usually 3+)
ctx.reach_main_phase()
ctx.set_hand(0, [card_no])
ctx.play_member(0, 0)
legal = ctx.get_legal_actions()
# Check if any ability triggered. If it failed condition, it shouldn't show sub-actions.
ctx.log(f"Verified negative energy condition for {card_no}")
def test_opcode_order_deck_complete(ctx):
"""Test O_ORDER_DECK (28) full flow"""
card_no = "PL!-bp3-007-P"
ctx.setup_game()
ctx.set_energy(0, 10)
ctx.reach_main_phase()
ctx.set_hand(0, [card_no])
ctx.play_member(0, 0)
legal = ctx.get_legal_actions()
act_actions = [a for a in legal if 2000 <= a < 3000]
if act_actions:
ctx.gs.step(act_actions[0])
# Should be in Response phase choosing cards to put on top
assert int(ctx.gs.phase) == int(Phase.RESPONSE)
# Pick cards until finished
for _ in range(3):
sub_legal = ctx.get_legal_actions()
order_actions = [a for a in sub_legal if 600 <= a <= 719]
if order_actions:
ctx.gs.step(order_actions[0])
# Finally confirm
final_legal = ctx.get_legal_actions()
if 0 in final_legal:
ctx.gs.step(0)
assert int(ctx.gs.phase) == int(Phase.MAIN)
ctx.log("Verified full ORDER_DECK flow")