kards-env/tests/test_card_system.py

295 lines
11 KiB
Python
Raw Permalink Normal View History

2025-09-05 17:05:43 +08:00
"""
卡牌系统测试
"""
import pytest
from kards_battle.core.enums import Nation, Rarity
from kards_battle.cards.card import UnitCard
from kards_battle.cards.deck import DeckBuilder, DeckValidationError
from kards_battle.cards.card_manager import CardManager
from kards_battle.cards.placeholder_cards import create_placeholder_unit_cards, create_test_deck_cards
from kards_battle.game.game_engine import GameEngine
class TestCardSystem:
"""卡牌系统基础测试"""
def test_unit_card_creation(self):
"""测试单位卡牌创建"""
card = UnitCard(
name="德军掷弹兵",
cost=2,
nation=Nation.GERMANY,
rarity=Rarity.COMMON,
unit_definition_id="ger_infantry_grenadier",
description="基础德军步兵单位"
)
assert card.name == "德军掷弹兵"
assert card.stats.cost == 2
assert card.stats.nation == Nation.GERMANY
assert card.stats.rarity == Rarity.COMMON
assert card.unit_definition_id == "ger_infantry_grenadier"
def test_placeholder_cards_creation(self):
"""测试占位卡牌创建"""
cards = create_placeholder_unit_cards()
assert len(cards) == 10
# 检查所有卡牌都是德国的
for card in cards:
assert card.stats.nation == Nation.GERMANY
assert card.stats.rarity == Rarity.COMMON
assert card.unit_definition_id == "ger_infantry_grenadier"
def test_deck_validation_success(self):
"""测试卡组验证成功案例"""
cards = create_test_deck_cards(Nation.GERMANY, Nation.ITALY)
# 应该能成功创建卡组
deck = DeckBuilder.build_deck(Nation.GERMANY, Nation.ITALY, cards)
assert deck.major_nation == Nation.GERMANY
assert deck.minor_nation == Nation.ITALY
assert len(deck.cards) == 39
# 获取统计信息
stats = deck.get_statistics()
assert stats['total_cards'] == 39
assert stats['major_nation'] == Nation.GERMANY
assert stats['minor_nation'] == Nation.ITALY
def test_deck_validation_invalid_count(self):
"""测试卡组验证:卡牌数量错误"""
cards = create_placeholder_unit_cards()[:5] # 只有5张卡
with pytest.raises(DeckValidationError, match="卡组必须包含39张卡牌"):
DeckBuilder.build_deck(Nation.GERMANY, Nation.ITALY, cards)
def test_deck_validation_invalid_major_nation(self):
"""测试卡组验证:无效主国"""
cards = create_test_deck_cards(Nation.GERMANY, Nation.ITALY)
with pytest.raises(DeckValidationError, match="主国.*不在允许的主要国家列表中"):
DeckBuilder.build_deck(Nation.FINLAND, Nation.ITALY, cards) # Finland不是主要国家
def test_deck_validation_same_nations(self):
"""测试卡组验证:主国和盟国相同"""
cards = create_test_deck_cards(Nation.GERMANY, Nation.GERMANY)
with pytest.raises(DeckValidationError, match="主国和盟国不能相同"):
DeckBuilder.build_deck(Nation.GERMANY, Nation.GERMANY, cards)
def test_card_manager_initialization(self):
"""测试卡牌管理器初始化"""
cards = create_test_deck_cards(Nation.GERMANY, Nation.ITALY)
deck = DeckBuilder.build_deck(Nation.GERMANY, Nation.ITALY, cards)
manager = CardManager(deck)
assert manager.cards_remaining_in_deck() == 39
assert manager.hand_size() == 0
assert len(manager.discard_pile) == 0
assert manager.fatigue_damage == 1
assert not manager.strategic_deployment_completed
def test_card_manager_initial_draw(self):
"""测试初始摸牌"""
cards = create_test_deck_cards(Nation.GERMANY, Nation.ITALY)
deck = DeckBuilder.build_deck(Nation.GERMANY, Nation.ITALY, cards)
manager = CardManager(deck)
drawn_cards = manager.initial_draw(5)
assert len(drawn_cards) == 5
assert manager.hand_size() == 5
assert manager.cards_remaining_in_deck() == 34
def test_card_manager_strategic_deployment(self):
"""测试战略调度"""
cards = create_test_deck_cards(Nation.GERMANY, Nation.ITALY)
deck = DeckBuilder.build_deck(Nation.GERMANY, Nation.ITALY, cards)
manager = CardManager(deck)
initial_cards = manager.initial_draw(4)
# 选择重抽2张牌
cards_to_mulligan = initial_cards[:2]
new_cards = manager.strategic_deployment(cards_to_mulligan)
assert len(new_cards) == 2
assert manager.hand_size() == 4 # 仍然是4张牌
assert manager.strategic_deployment_completed
# 不应该能再次进行战略调度
with pytest.raises(ValueError, match="战略调度已经完成"):
manager.strategic_deployment([])
def test_card_manager_fatigue_system(self):
"""测试疲劳系统"""
# 创建一个小卡组用于快速测试疲劳
small_cards = []
# 主国卡27张
for i in range(9): # 9种不同的卡
for j in range(3): # 每种3张
card = UnitCard(
name=f"德军测试卡{i}",
cost=1,
nation=Nation.GERMANY,
rarity=Rarity.COMMON,
unit_definition_id="ger_infantry_grenadier",
description="测试用德军卡牌"
)
small_cards.append(card)
# 盟国卡12张
for i in range(4): # 4种不同的卡
for j in range(3): # 每种3张
card = UnitCard(
name=f"意军测试卡{i}",
cost=1,
nation=Nation.ITALY,
rarity=Rarity.COMMON,
unit_definition_id="ger_infantry_grenadier",
description="测试用意军卡牌"
)
small_cards.append(card)
deck = DeckBuilder.build_deck(Nation.GERMANY, Nation.ITALY, small_cards)
manager = CardManager(deck)
# 抽完所有牌
while manager.can_draw_safely():
manager.draw_card()
assert manager.cards_remaining_in_deck() == 0
# 记录疲劳伤害
fatigue_damages = []
def hq_damage_callback(damage):
fatigue_damages.append(damage)
# 继续抽牌应该造成疲劳伤害
result = manager.draw_card(hq_damage_callback)
assert result is None
assert len(fatigue_damages) == 1
assert fatigue_damages[0] == 1
assert manager.fatigue_damage == 2 # 递增
# 再次抽牌
result = manager.draw_card(hq_damage_callback)
assert result is None
assert len(fatigue_damages) == 2
assert fatigue_damages[1] == 2
assert manager.fatigue_damage == 3
class TestGameEngine:
"""游戏引擎测试"""
def test_game_engine_creation(self):
"""测试游戏引擎创建"""
engine = GameEngine(debug_mode=True)
game_state = engine.create_test_game(
"Player1", Nation.GERMANY, Nation.ITALY,
"Player2", Nation.USA, Nation.UK
)
assert game_state is not None
assert game_state.player1.name == "Player1"
assert game_state.player2.name == "Player2"
assert game_state.player1.major_nation == Nation.GERMANY
assert game_state.player1.minor_nation == Nation.ITALY
assert game_state.player2.major_nation == Nation.USA
assert game_state.player2.minor_nation == Nation.UK
def test_strategic_deployment_phase(self):
"""测试战略调度阶段"""
engine = GameEngine(debug_mode=True)
game_state = engine.create_test_game()
# 初始阶段应该是战略调度
from kards_battle.game.game_state import GameStatePhase
assert game_state.phase == GameStatePhase.STRATEGIC_DEPLOYMENT
# 玩家应该可以进行战略调度
assert game_state.can_perform_strategic_deployment(0)
assert game_state.can_perform_strategic_deployment(1)
# 玩家1进行战略调度不重抽任何牌
player1_hand = game_state.player1.card_manager.get_hand_copy()
new_cards = engine.perform_strategic_deployment(0, [])
assert len(new_cards) == 0
assert not game_state.can_perform_strategic_deployment(0)
# 玩家2进行战略调度重抽1张牌
player2_hand = game_state.player2.card_manager.get_hand_copy()
cards_to_mulligan = [player2_hand[0]]
new_cards = engine.perform_strategic_deployment(1, cards_to_mulligan)
assert len(new_cards) == 1
assert not game_state.can_perform_strategic_deployment(1)
# 现在应该可以开始正式游戏
engine.start_main_game()
assert game_state.phase == GameStatePhase.GAME_ACTIVE
def test_game_flow(self):
"""测试基本游戏流程"""
engine = GameEngine(debug_mode=True)
game_state = engine.create_test_game()
# 跳过战略调度,直接开始游戏
engine.start_main_game()
# 检查初始状态
assert game_state.current_turn == 1
assert game_state.active_player_id == 0 # 先手
# 当前玩家应该有kredits
current_player = game_state.get_current_player()
assert current_player.kredits > 0
assert current_player.kredits_slot > 0
# 获取可打出的卡牌
playable_cards = engine.get_playable_cards(0)
# 第一回合可能没有可打出的卡牌,这是正常的
assert isinstance(playable_cards, list)
# 结束回合
engine.end_turn(0)
# 应该轮到玩家2
assert game_state.active_player_id == 1
# 玩家2也应该有kredits
player2 = game_state.get_current_player()
assert player2.kredits > 0
def test_card_playing(self):
"""测试打牌功能"""
engine = GameEngine(debug_mode=True)
game_state = engine.create_test_game()
engine.start_main_game()
# 获取当前玩家的可打出卡牌
current_player_id = game_state.active_player_id
playable_cards = engine.get_playable_cards(current_player_id)
if playable_cards:
# 尝试打出一张单位卡
for card in playable_cards:
if hasattr(card, 'unit_definition_id'): # 是单位卡
initial_kredits = game_state.get_current_player().kredits
success = engine.play_unit_card(current_player_id, card)
if success:
# 检查kredits是否扣除
final_kredits = game_state.get_current_player().kredits
assert final_kredits == initial_kredits - card.stats.cost
# 检查卡牌是否从手牌移除
current_hand = engine.get_player_hand(current_player_id)
assert card not in current_hand
break