""" 卡牌系统测试 """ 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