Spaces:
Running
Running
File size: 5,320 Bytes
bb3fbf9 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
import os
import sys
# Add project root to path
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "../../../")))
import os
from engine.game.data_loader import CardDataLoader
from engine.game.enums import Phase
from engine.game.game_state import GameState
# Mock DB loader if needed, or use real one
def get_test_db():
base_path = os.path.dirname(os.path.abspath(__file__))
project_root = os.path.abspath(os.path.join(base_path, "../../../"))
cards_path = os.path.join(project_root, "data/cards.json")
loader = CardDataLoader(cards_path)
return loader.load()
def test_order_deck_logic():
m, l, e = get_test_db()
# Initialize DB for GameState
GameState.initialize_class_db(m, l)
GameState.energy_db = e
GameState._init_jit_arrays()
gs = GameState()
p0 = gs.players[0]
# Find PL!N-bp1-002-P (Nakasuv Kasumi)
# Trigger: ON_PLAY -> LOOK_AND_CHOOSE_ORDER(3) -> DECK_TOP
target_card_no = "PL!N-bp1-002-P"
target_card_id = -1
for cid, card in m.items():
if card.card_no == target_card_no:
target_card_id = int(cid)
break
assert target_card_id != -1, f"Card {target_card_no} not found in DB"
# Isolate card in hand, clear deck to controllable state
p0.hand = [target_card_id]
p0.energy_zone = [20000, 20000] # Enough energy
# Fix: Ensure tapped_energy is numpy array
import numpy as np
p0.tapped_energy = np.zeros(100, dtype=bool)
p0.tapped_energy[0] = False
p0.tapped_energy[1] = False
# Setup Deck: [C, B, A] -> Top is A
# We want known cards to verify ordering
# Let's use some dummy IDs if possible or just other members
deck_cards = [1001, 1002, 1003, 1004, 1005] # Assumptions
p0.deck = deck_cards[:]
# Setup Phase
gs.phase = Phase.MAIN
gs.current_player = 0
gs.turn = 1
print("\n--- Playing Card ---\n")
# Play to Center (Slot 1). Action ID: 1 + 0*3 + 1 = 2
gs.step(2)
print("DEBUG RULE LOG:", gs.rule_log)
# 1. Verify we paused for ORDER_DECK
assert gs.phase == Phase.RESPONSE, f"Expected Response phase, got {gs.phase}"
assert gs.pending_choice_type == "ORDER_DECK", f"Expected ORDER_DECK choice, got {gs.pending_choice_type}"
# 2. Verify looked_cards populated
looked = p0.looked_cards
print(f"Looked Cards: {looked}")
assert len(looked) == 3, f"Expected 3 looked cards, got {len(looked)}"
# Should be the popped cards from deck. Since deck pops from end:
# Deck was [..., 1003, 1004, 1005]
# Pop 1: 1005, Pop 2: 1004, Pop 3: 1003
# Looked should be [1005, 1004, 1003] (or visible order)
# 3. Check Legal Actions
# Should offer choices 0, 1, 2 (corresponding to the 3 cards)
# Action ID range: 550 + area_idx*100 + ab_idx*10 + c
# area_idx = 1 (Center)
# ab_idx for OnPlay usually -1 -> mapped to 0 safely in our new logic?
# Let's check get_legal_actions output mask
legal_mask = gs.get_legal_actions()
legal_indices = [i for i, v in enumerate(legal_mask) if v]
print(f"Legal Actions: {legal_indices}")
# Calculate Expected IDs
# area=1, ab=0 (safe_ab), c=0..2
# 550 + 100 + 0 + 0 = 650
# 550 + 100 + 0 + 1 = 651
# 550 + 100 + 0 + 2 = 652
expected_ids = [650, 651, 652]
for eid in expected_ids:
assert eid in legal_indices, f"Expected Action ID {eid} not found in {legal_indices}"
print("\n--- Selecting First Card to Top ---\n")
# Choose Index 1 (Card 1004) to put on TOP
gs.step(651)
# 4. Verify Card Moved
# Deck should now have 1004 on top (end of list)
assert p0.deck[-1] == looked[1], "Chosen card not on top of deck"
# 5. Verify Loop (Still in Response, fewer cards)
assert gs.phase == Phase.RESPONSE, "Should still be in Response phase for next card"
assert len(p0.looked_cards) == 2, "Should have 2 cards left in looked_cards"
print("\n--- Discarding Rest ---\n")
# If we want to test "Done"/Discard logic, we need to know what ID triggers that.
# In my implementation plan, I said "Invalid choice implies discard rest".
# But get_legal_actions only gives valid choices [0, 1].
# Wait, the logic handles "Invalid choice" but UI prevents it usually.
# The logic says: `if choice >= 0 && choice < looked_len: ... else: discard all`
# So we need to send an action that maps to a choice >= looked_len?
# Or maybe we rely on the fact that we can just pick all cards one by one.
# Let's pick another card. Index 0 of REMAINING list.
# Remaining: [1005, 1003] (Original 0 and 2)
# We pick 1005 (Current Index 0)
gs.step(650) # Same ID 650 is valid for index 0
assert p0.deck[-1] == looked[0], "Next chosen card not on top"
assert len(p0.looked_cards) == 1
# Pick last card
gs.step(650)
assert p0.deck[-1] == looked[2], "Last card not on top"
assert len(p0.looked_cards) == 0
# 6. Verify Phase Transition
assert gs.phase == Phase.MAIN, "Should return to Main phase after cards depleted"
print("Test Passed: O_ORDER_DECK logic verified.")
if __name__ == "__main__":
test_order_deck_logic()
|