LovecaSim / engine /tests /mechanics /test_triggers_missing.py
trioskosmos's picture
Upload folder using huggingface_hub
bb3fbf9 verified
import json
from engine_rust import PyCardDatabase, PyGameState
from engine.models.ability import Ability, Effect, EffectType, TargetType, TriggerType
from engine.models.opcodes import Opcode
def create_mock_db_json(cards):
"""Create a JSON string for PyCardDatabase."""
db_data = {"members": {}, "lives": {}}
for card in cards:
card_data = {
"card_id": card["card_id"],
"card_no": card.get("card_no", "TEST-001"),
"name": card.get("name", "Test Card"),
"cost": card.get("cost", 1),
"hearts": card.get("hearts", [0] * 7),
"blade_hearts": card.get("blade_hearts", [0] * 7),
"blades": card.get("blades", 0),
"groups": card.get("groups", []),
"units": card.get("units", []),
"abilities": card.get("abilities", []),
"volume_icons": card.get("volume_icons", 0),
"draw_icons": card.get("draw_icons", 0),
"img_path": "",
"ability_text": "",
}
db_data["members"][str(card["card_id"])] = card_data
return json.dumps(db_data)
def test_on_reveal_trigger():
"""Verify that OnReveal triggers when a card is yelled."""
ab = Ability(
raw_text="OnReveal: Draw 1",
trigger=TriggerType.ON_REVEAL,
effects=[Effect(EffectType.DRAW, value=1, target=TargetType.SELF)],
)
bytecode = ab.compile()
cards = [
{
"card_id": 101,
"abilities": [
{
"trigger": int(TriggerType.ON_REVEAL),
"bytecode": bytecode,
"conditions": [],
"raw_text": "OnReveal: Draw 1",
}
],
}
]
db = PyCardDatabase(create_mock_db_json(cards))
gs = PyGameState(db)
# Setup Deck using PyGameState setter
# PyGameState.initialize_game(p0_deck, p1_deck, p0_energy, p1_energy, p0_lives, p1_lives)
gs.initialize_game(
[302, 301, 101], # p0 deck (101 on top)
[],
[],
[],
[],
[],
)
# Action 1 = Yell
gs.set_phase(4) # Main Phase
p0 = gs.get_player(0)
p0.set_blade_buffs([1, 0, 0])
gs.set_player(0, p0)
gs.step(1)
p0_after = gs.get_player(0)
assert 301 in p0_after.hand
def test_on_leaves_trigger():
"""Verify that OnLeaves triggers when a card is replaced on stage."""
ab_leaves = Ability(
raw_text="OnLeaves: Draw 1",
trigger=TriggerType.ON_LEAVES,
effects=[Effect(EffectType.DRAW, value=1, target=TargetType.SELF)],
)
cards = [
{
"card_id": 101,
"abilities": [
{
"trigger": int(TriggerType.ON_LEAVES),
"bytecode": ab_leaves.compile(),
"conditions": [],
"raw_text": "OnLeaves: Draw 1",
}
],
},
{"card_id": 102, "abilities": []},
]
db = PyCardDatabase(create_mock_db_json(cards))
gs = PyGameState(db)
gs.initialize_game(
[301, 302], # p0 deck
[],
[],
[],
[],
[],
)
# Set stage and hand via PyGameState
gs.set_stage_card(0, 0, 101)
gs.set_hand_cards(0, [102])
# O_PLAY_MEMBER_FROM_HAND (57)
bytecode = [Opcode.PLAY_MEMBER_FROM_HAND, 0, 0, 0, Opcode.RETURN, 0, 0, 0]
gs.debug_execute_bytecode(bytecode, 0, 0, -1, 0, 0, 0)
p0_after = gs.get_player(0)
if p0_after.stage[0] != 102 or 301 not in p0_after.hand:
raise Exception(
f"DEBUG OnLeaves FAILED.\nStage: {p0_after.stage}\nHand: {p0_after.hand}\nDiscard: {p0_after.discard}\nLog: {gs.rule_log}"
)
def test_on_position_change_trigger():
"""Verify that OnPositionChange triggers when a card moves slots."""
ab_pos = Ability(
raw_text="OnPosition: Draw 1",
trigger=TriggerType.ON_POSITION_CHANGE,
effects=[Effect(EffectType.DRAW, value=1, target=TargetType.SELF)],
)
cards = [
{
"card_id": 101,
"abilities": [
{
"trigger": int(TriggerType.ON_POSITION_CHANGE),
"bytecode": ab_pos.compile(),
"conditions": [],
"raw_text": "OnPosition: Draw 1",
}
],
}
]
db = PyCardDatabase(create_mock_db_json(cards))
gs = PyGameState(db)
gs.initialize_game(
[301, 302], # p0 deck
[],
[],
[],
[],
[],
)
gs.set_stage_card(0, 0, 101)
# O_MOVE_MEMBER (20)
bytecode = [Opcode.MOVE_MEMBER, 0, 0, 2, Opcode.RETURN, 0, 0, 0]
gs.debug_execute_bytecode(bytecode, 0, 0, -1, 2, 0, 0)
p0_after = gs.get_player(0)
if p0_after.stage[2] != 101 or 301 not in p0_after.hand:
raise Exception(f"DEBUG OnPosition FAILED.\nStage: {p0_after.stage}\nHand: {p0_after.hand}\nLog: {gs.rule_log}")