kards-env/kards_battle/game/game_engine.py

360 lines
11 KiB
Python
Raw Permalink Normal View History

2025-09-05 17:05:43 +08:00
"""
游戏主引擎 - 协调卡牌系统和战斗系统
"""
from typing import List, Optional, Tuple, Dict, Any
from ..core.enums import Nation, LineType
from ..cards.deck import Deck, DeckBuilder
from ..cards.card import BaseCard, UnitCard
from ..cards.placeholder_cards import create_test_deck_cards
from .game_state import GameState, GameStatePhase
from .nation_config import NationConfig
class GameEngineError(Exception):
"""游戏引擎错误"""
pass
class GameEngine:
"""
游戏主引擎
协调卡牌系统和战斗系统管理完整的游戏流程
"""
def __init__(self, debug_mode: bool = False):
self.debug_mode = debug_mode
self.game_state: Optional[GameState] = None
def create_test_game(
self,
player1_name: str = "Player1",
player1_major: Nation = Nation.GERMANY,
player1_minor: Nation = Nation.ITALY,
player2_name: str = "Player2",
player2_major: Nation = Nation.USA,
player2_minor: Nation = Nation.UK
) -> GameState:
"""
创建测试游戏
Args:
player1_name: 玩家1名称
player1_major: 玩家1主国
player1_minor: 玩家1盟国
player2_name: 玩家2名称
player2_major: 玩家2主国
player2_minor: 玩家2盟国
Returns:
游戏状态对象
"""
# 验证国家配置
if not NationConfig.is_valid_major_minor_combo(player1_major, player1_minor):
raise GameEngineError(f"玩家1的国家组合无效: {player1_major}/{player1_minor}")
if not NationConfig.is_valid_major_minor_combo(player2_major, player2_minor):
raise GameEngineError(f"玩家2的国家组合无效: {player2_major}/{player2_minor}")
# 创建测试卡组
player1_cards = create_test_deck_cards(player1_major, player1_minor)
player2_cards = create_test_deck_cards(player2_major, player2_minor)
# 构建卡组
player1_deck = DeckBuilder.build_deck(player1_major, player1_minor, player1_cards)
player2_deck = DeckBuilder.build_deck(player2_major, player2_minor, player2_cards)
# 创建游戏状态
self.game_state = GameState(
player1_name, player1_deck,
player2_name, player2_deck,
debug_mode=self.debug_mode
)
if self.debug_mode:
print(f"测试游戏创建成功:")
print(f" {player1_name}: {player1_major}/{player1_minor}")
print(f" {player2_name}: {player2_major}/{player2_minor}")
return self.game_state
def create_game_from_decks(
self,
player1_name: str,
player1_deck: Deck,
player2_name: str,
player2_deck: Deck
) -> GameState:
"""
从预构建的卡组创建游戏
Args:
player1_name: 玩家1名称
player1_deck: 玩家1卡组
player2_name: 玩家2名称
player2_deck: 玩家2卡组
Returns:
游戏状态对象
"""
self.game_state = GameState(
player1_name, player1_deck,
player2_name, player2_deck,
debug_mode=self.debug_mode
)
return self.game_state
def get_current_game(self) -> Optional[GameState]:
"""获取当前游戏状态"""
return self.game_state
def perform_strategic_deployment(
self,
player_id: int,
cards_to_mulligan: List[BaseCard]
) -> List[BaseCard]:
"""
执行战略调度
Args:
player_id: 玩家ID
cards_to_mulligan: 要重抽的卡牌列表
Returns:
新抽到的卡牌列表
"""
if not self.game_state:
raise GameEngineError("游戏尚未创建")
return self.game_state.perform_strategic_deployment(player_id, cards_to_mulligan)
def start_main_game(self):
"""开始正式游戏(完成战略调度阶段后)"""
if not self.game_state:
raise GameEngineError("游戏尚未创建")
self.game_state.start_main_game()
if self.debug_mode:
print("正式游戏开始!")
def play_unit_card(
self,
player_id: int,
card: UnitCard,
target_position: Optional[Tuple[LineType, int]] = None
) -> bool:
"""
打出单位卡牌
Args:
player_id: 玩家ID
card: 要打出的单位卡
target_position: 目标位置 (line_type, position)
Returns:
是否成功打出
"""
if not self.game_state:
raise GameEngineError("游戏尚未创建")
if self.game_state.active_player_id != player_id:
raise GameEngineError("不是该玩家的回合")
player = self.game_state.get_player(player_id)
# 检查卡牌是否在手中
if card not in player.card_manager.hand:
raise GameEngineError("卡牌不在手牌中")
# 检查是否有足够的kredits
if player.kredits < card.stats.cost:
raise GameEngineError(f"Kredits不足: 需要{card.stats.cost},当前{player.kredits}")
# 检查卡牌是否可以打出
if not card.can_be_played(self.game_state):
raise GameEngineError("当前无法打出该卡牌")
# 执行卡牌效果
success = card.play_effect(self.game_state, target_position)
if success:
# 从手牌移除卡牌
player.card_manager.play_card_from_hand(card)
# 将卡牌放入弃牌堆
player.card_manager.discard_card(card)
if self.debug_mode:
print(f"{player.name} 打出 {card.name} (费用: {card.stats.cost})")
return True
return False
def move_unit(
self,
player_id: int,
unit_id: str,
target_position: Tuple[LineType, int]
) -> bool:
"""
移动单位
Args:
player_id: 玩家ID
unit_id: 单位ID
target_position: 目标位置
Returns:
是否移动成功
"""
if not self.game_state:
raise GameEngineError("游戏尚未创建")
if self.game_state.active_player_id != player_id:
raise GameEngineError("不是该玩家的回合")
# 使用战斗引擎执行移动
result = self.game_state.battle_engine.move_unit(unit_id, target_position, player_id)
if self.debug_mode and result.success:
print(f"{self.game_state.get_player(player_id).name} 移动单位成功")
return result.success
def attack_with_unit(
self,
player_id: int,
attacker_id: str,
target_id: str
) -> bool:
"""
使用单位攻击
Args:
player_id: 玩家ID
attacker_id: 攻击者单位ID
target_id: 目标单位ID
Returns:
是否攻击成功
"""
if not self.game_state:
raise GameEngineError("游戏尚未创建")
if self.game_state.active_player_id != player_id:
raise GameEngineError("不是该玩家的回合")
# 使用战斗引擎执行攻击
result = self.game_state.battle_engine.attack_unit(attacker_id, target_id, player_id)
if result.success:
# 检查游戏胜利条件
self.game_state.check_win_condition()
if self.debug_mode:
print(f"{self.game_state.get_player(player_id).name} 攻击成功")
return result.success
def end_turn(self, player_id: int):
"""
结束回合
Args:
player_id: 玩家ID
"""
if not self.game_state:
raise GameEngineError("游戏尚未创建")
if self.game_state.active_player_id != player_id:
raise GameEngineError("不是该玩家的回合")
self.game_state.end_turn()
# 检查游戏胜利条件
self.game_state.check_win_condition()
def get_player_hand(self, player_id: int) -> List[BaseCard]:
"""
获取玩家手牌
Args:
player_id: 玩家ID
Returns:
手牌列表
"""
if not self.game_state:
raise GameEngineError("游戏尚未创建")
return self.game_state.get_player(player_id).card_manager.get_hand_copy()
def get_playable_cards(self, player_id: int) -> List[BaseCard]:
"""
获取玩家当前可以打出的卡牌
Args:
player_id: 玩家ID
Returns:
可打出的卡牌列表
"""
if not self.game_state:
raise GameEngineError("游戏尚未创建")
player = self.game_state.get_player(player_id)
return player.card_manager.get_playable_cards(player.kredits)
def get_battlefield_state(self) -> Dict[str, Any]:
"""
获取战场状态
Returns:
战场状态字典
"""
if not self.game_state:
raise GameEngineError("游戏尚未创建")
battlefield = self.game_state.get_battlefield()
return {
'player1_support': {
'units': [str(unit) for unit in battlefield.player1_support.get_units()],
'hq': str(battlefield.player1_support.get_hq()) if battlefield.player1_support.get_hq() else None
},
'front_line': {
'units': [str(unit) for unit in battlefield.front_line.get_units()]
},
'player2_support': {
'units': [str(unit) for unit in battlefield.player2_support.get_units()],
'hq': str(battlefield.player2_support.get_hq()) if battlefield.player2_support.get_hq() else None
}
}
def get_game_statistics(self) -> Dict[str, Any]:
"""
获取游戏统计信息
Returns:
游戏统计信息字典
"""
if not self.game_state:
return {'error': '游戏尚未创建'}
return self.game_state.get_game_statistics()
def is_game_over(self) -> bool:
"""检查游戏是否结束"""
return self.game_state and self.game_state.game_ended
def get_winner(self) -> Optional[str]:
"""获取游戏获胜者"""
if not self.game_state or not self.game_state.game_ended:
return None
if self.game_state.winner_id is not None:
return self.game_state.get_player(self.game_state.winner_id).name
return None