import json import os import sys # Setup paths 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) import engine_rust def test_kasumi_movement(): # Load compiled data compiled_path = os.path.join(PROJECT_ROOT, "data", "cards_compiled.json") with open(compiled_path, "r", encoding="utf-8") as f: db = engine_rust.PyCardDatabase(f.read()) gs = engine_rust.PyGameState(db) # Setup: Kasumi PL!N-bp1-002-P (ID: 57401 or similar, let's find it) # The ID for PL!N-bp1-002-P in compiled data is likely 57401 + instance bits # Let's search for it with open(compiled_path, "r", encoding="utf-8") as f: data = json.load(f) kasumi_base_id = -1 for cid, card in data["member_db"].items(): if card.get("card_no") == "PL!N-bp1-002-P": kasumi_base_id = int(cid) break assert kasumi_base_id != -1, "Kasumi card not found in database" # Initialize game with minimal decks p0_deck = [kasumi_base_id] * 20 p1_deck = [kasumi_base_id] * 20 gs.initialize_game(p0_deck, p1_deck, [], [], [], []) # 1. Put Kasumi in discard p0 = gs.get_player(0) p0.discard = [kasumi_base_id] gs.set_player(0, p0) # 2. Give enough energy p0 = gs.get_player(0) p0.energy_zone = [1, 1] p0.tapped_energy = [False, False] gs.set_player(0, p0) # 3. Discard a card from hand (cost requirement) p0 = gs.get_player(0) other_card_id = 100 # Some random ID p0.hand = [other_card_id] gs.set_player(0, p0) # Set phase to Main gs.phase = 4 print( f"Initial State: Discard={gs.get_player(0).discard}, Hand={gs.get_player(0).hand}, Stage={gs.get_player(0).stage}" ) # 4. Find the action ID for the activated ability # Activated Ability for Kasumi in discard is at index 1 # 2000 + discard_idx * 10 + ability_idx = 2000 + 0 * 10 + 1 = 2001 action_id = 2001 # Execute action gs.step(action_id) print("--- LOGS AFTER 2001 ---") for log in gs.rule_log: print(f"LOG: {log}") print(f"After Action 2001: Phase={gs.phase}, Pending Choice Type='{gs.pending_choice_type}'") # 5. It should ask for a slot (O_PLAY_MEMBER_FROM_DISCARD pauses) # Action ID for slot 0 is 560 gs.step(560) print("--- LOGS AFTER 560 ---") for log in gs.rule_log: print(f"LOG: {log}") # 6. Check if Kasumi is on stage final_p0 = gs.get_player(0) print(f"Final State: Discard={final_p0.discard}, Hand={final_p0.hand}, Stage={final_p0.stage}") assert final_p0.stage[0] == kasumi_base_id, ( f"Expected Kasumi ({kasumi_base_id}) on Stage slot 0, found {final_p0.stage[0]}" ) # Hand card should now be in discard (cost was DISCARD_HAND(1)) assert other_card_id in final_p0.discard, ( f"Expected other card ({other_card_id}) in discard, found {final_p0.discard}" ) assert kasumi_base_id not in final_p0.discard, "Kasumi should have moved to stage" # Actually, cost of PL!N-bp1-002-P is Discard 1 + Energy 2. # So hand card (1) should be in discard. # Wait, the hand card was Kasumi too. # Let's check rule logs. for log in gs.rule_log: print(f"LOG: {log}") print("SUCCESS: Kasumi moved to stage correctly!") if __name__ == "__main__": test_kasumi_movement()