LovecaSim / engine /tests /mechanics /test_live_placement.py
trioskosmos's picture
Upload folder using huggingface_hub
bb3fbf9 verified
from engine.game.enums import Phase
from engine.game.game_state import GameState
from engine.models.card import LiveCard, MemberCard
def test_play_member_to_live_zone():
"""Test playing a Member card to Live Zone (Rule 8.2.2)"""
# Initialize DB to avoid empty DB issues
from engine.models.card import MemberCard
GameState.member_db[1] = MemberCard(
card_id=1, card_no="M1", name="Test", cost=1, blades=1, hearts=[1] * 7, blade_hearts=[0] * 7
)
game = GameState()
# Setup: Phase to LIVE_SET
game.phase = Phase.LIVE_SET
p = game.players[game.current_player]
# Ensure hand has a Member card
if not p.hand:
p.hand.append(1) # Add dummy card
# Ensure deck has cards for drawing
p.main_deck = [200, 201]
initial_hand_size = len(p.hand)
initial_deck_size = len(p.main_deck)
card_to_play = p.hand[0]
# Debug legality
legal_mask = game.get_legal_actions()
print(f"Action 400 Legal: {legal_mask[400]}")
if not legal_mask[400]:
print("Legal actions indices:", [i for i, v in enumerate(legal_mask) if v])
# Action: Play first card (Action 400)
# Action 400 corresponds to index 0 of hand
game = game.step(400)
p = game.players[game.current_player]
# Assertions
# 1. Card should be in Live Zone
assert card_to_play in p.live_zone, f"Card {card_to_play} not in live zone {p.live_zone}"
assert len(p.live_zone) == 1
# 2. Hand size should DECREASE by 1 (Play 1, Draw deferred)
# The draw happens at END of LIVE_SET (Action 0)
assert len(p.hand) == initial_hand_size - 1, f"Hand size {len(p.hand)} != {initial_hand_size - 1}"
# Deck should be same until draw
assert len(p.main_deck) == initial_deck_size
def test_live_zone_cleanup():
"""Test cleanup of non-Live cards at start of Performance (Rule 8.3.4)"""
game = GameState()
p = game.active_player
# Setup: Inject 1 Member (ID < 100) and 1 Live (ID > 100)
member_id = 99
live_id = 101
# Mock DB presence
# Add required fields for MemberCard
GameState.member_db[member_id] = MemberCard(
card_id=member_id,
card_no="M1",
name="M",
cost=1,
blades=1,
hearts=[1, 0, 0, 0, 0, 0, 0],
blade_hearts=[1, 0, 0, 0, 0, 0, 0],
)
# Ensure live_id is in live_db so it isn't cleaned up
GameState.live_db[live_id] = LiveCard(card_id=live_id, card_no="L1", name="L", score=1, required_hearts=[0] * 7)
p.live_zone = [member_id, live_id]
p.live_zone_revealed = [False, False]
p.main_deck = [200]
# Force Phase to PERFORMANCE_P1 (or whichever matches active player)
# PhaseMixin._do_performance checks current player
game.phase = Phase.PERFORMANCE_P1 if game.current_player == 0 else Phase.PERFORMANCE_P2
# We need to trigger the performance start logic.
# calling step(0) (Pass) generally triggers processing if we are in that phase
p_idx = game.active_player.player_id
game = game.step(0)
p = game.players[p_idx] # Keep checking the same player
# Check Cleanup
# Member ID should be gone (moved to discard)
# Live ID should remain (or be processed/failed, but initially it stays for check)
# Note: _do_performance might discard Live card if logic runs and fails immediately
# But specifically, the member card is discarded due to "Not being a Live Card"
# whereas the Live card is discarded due to "Failure" later.
# To differentiate, we can check logs or step through.
# But result-wise: Member card MUST be in discard.
assert member_id not in p.live_zone
assert member_id in p.discard
# If requirements fail (which they will with 0 hearts on stage), live_id also goes to discard
# But let's verification focus on the Member ID being handled.