""" 游戏状态管理 """ from typing import Optional, Dict, Any, List from dataclasses import dataclass from enum import Enum, auto from ..core.enums import Nation, GamePhase from ..core.battle_engine import BattleEngine from ..cards.card_manager import CardManager from ..cards.deck import Deck from ..cards.card import BaseCard, CounterCard class GameStatePhase(Enum): """游戏阶段枚举""" INITIALIZATION = auto() # 初始化阶段 STRATEGIC_DEPLOYMENT = auto() # 战略调度阶段 GAME_ACTIVE = auto() # 游戏进行阶段 GAME_ENDED = auto() # 游戏结束阶段 @dataclass class PlayerState: """玩家状态""" name: str player_id: int # 0 或 1 major_nation: Nation minor_nation: Nation card_manager: CardManager kredits: int = 0 # 当前可用kredits kredits_slot: int = 0 # kredits槽数 set_counters: List[CounterCard] = None # 已设置的反制卡 def __post_init__(self): if self.set_counters is None: self.set_counters = [] class GameState: """游戏状态管理器""" def __init__( self, player1_name: str, player1_deck: Deck, player2_name: str, player2_deck: Deck, debug_mode: bool = False ): # 基础游戏信息 self.debug_mode = debug_mode self.phase = GameStatePhase.INITIALIZATION # 创建战斗引擎 self.battle_engine = BattleEngine(player1_name, player2_name, debug_mode) # 创建玩家状态 self.player1 = PlayerState( name=player1_name, player_id=0, major_nation=player1_deck.major_nation, minor_nation=player1_deck.minor_nation, card_manager=CardManager(player1_deck) ) self.player2 = PlayerState( name=player2_name, player_id=1, major_nation=player2_deck.major_nation, minor_nation=player2_deck.minor_nation, card_manager=CardManager(player2_deck) ) # 游戏流程状态 self.current_turn = 1 self.active_player_id = 0 # 当前行动玩家 (0 或 1) # 先后手确定 self.first_player_id = 0 # 先手玩家 self.second_player_id = 1 # 后手玩家 # 游戏结束状态 self.game_ended = False self.winner_id: Optional[int] = None self.end_reason = "" # 事件历史 self.event_history = [] # 初始化游戏 self._initialize_game() def _initialize_game(self): """初始化游戏状态""" # 部署HQ到战场 self._deploy_hqs() # 初始抽牌 self._initial_card_draw() # 进入战略调度阶段 self.phase = GameStatePhase.STRATEGIC_DEPLOYMENT if self.debug_mode: print(f"游戏初始化完成") print(f"先手玩家: {self.get_player(self.first_player_id).name}") print(f"后手玩家: {self.get_player(self.second_player_id).name}") def _deploy_hqs(self): """部署双方的HQ到战场""" # 创建HQ并部署到支援线 from ..battlefield.battlefield import HQ # 玩家1的HQ hq1 = HQ(player_id=self.player1.name) self.battle_engine.battlefield.player1_support.objectives.append(hq1) # 玩家2的HQ hq2 = HQ(player_id=self.player2.name) self.battle_engine.battlefield.player2_support.objectives.append(hq2) if self.debug_mode: print(f"HQ部署完成: {self.player1.name} vs {self.player2.name}") def _initial_card_draw(self): """初始抽牌""" # 先手玩家摸4张牌 first_player = self.get_player(self.first_player_id) first_cards = first_player.card_manager.initial_draw(4) # 后手玩家摸5张牌 second_player = self.get_player(self.second_player_id) second_cards = second_player.card_manager.initial_draw(5) if self.debug_mode: print(f"{first_player.name} 初始摸牌: {len(first_cards)}张") print(f"{second_player.name} 初始摸牌: {len(second_cards)}张") def get_player(self, player_id: int) -> PlayerState: """获取玩家状态""" if player_id == 0: return self.player1 elif player_id == 1: return self.player2 else: raise ValueError(f"无效的玩家ID: {player_id}") def get_current_player(self) -> PlayerState: """获取当前行动玩家""" return self.get_player(self.active_player_id) def get_opponent(self, player_id: int) -> PlayerState: """获取对手玩家""" return self.get_player(1 - player_id) def get_current_player_id(self) -> int: """获取当前行动玩家ID""" return self.active_player_id def get_battlefield(self): """获取战场""" return self.battle_engine.battlefield def get_battle_engine(self) -> BattleEngine: """获取战斗引擎""" return self.battle_engine def can_perform_strategic_deployment(self, player_id: int) -> bool: """检查玩家是否可以进行战略调度""" if self.phase != GameStatePhase.STRATEGIC_DEPLOYMENT: return False player = self.get_player(player_id) return not player.card_manager.strategic_deployment_completed 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.can_perform_strategic_deployment(player_id): raise ValueError("当前不能进行战略调度") player = self.get_player(player_id) new_cards = player.card_manager.strategic_deployment(cards_to_mulligan) if self.debug_mode: print(f"{player.name} 完成战略调度,重抽了 {len(cards_to_mulligan)} 张牌") return new_cards def is_strategic_deployment_complete(self) -> bool: """检查是否所有玩家都完成了战略调度""" return (self.player1.card_manager.strategic_deployment_completed and self.player2.card_manager.strategic_deployment_completed) def start_main_game(self): """开始正式游戏""" if self.phase != GameStatePhase.STRATEGIC_DEPLOYMENT: raise ValueError("必须在战略调度阶段后才能开始正式游戏") if not self.is_strategic_deployment_complete(): # 自动完成未完成的战略调度(不重抽任何卡) if not self.player1.card_manager.strategic_deployment_completed: self.perform_strategic_deployment(0, []) if not self.player2.card_manager.strategic_deployment_completed: self.perform_strategic_deployment(1, []) # 进入游戏进行阶段 self.phase = GameStatePhase.GAME_ACTIVE # 设置当前玩家为先手 self.active_player_id = self.first_player_id # 开始先手玩家的第一回合(不摸牌) self._start_player_turn(draw_card=False) if self.debug_mode: print(f"正式游戏开始,先手玩家: {self.get_current_player().name}") def _start_player_turn(self, draw_card: bool = True): """ 开始玩家回合 Args: draw_card: 是否摸牌(先手第一回合不摸牌) """ current_player = self.get_current_player() # 更新kredits系统 self._update_kredits_system() # 摸牌(除了先手第一回合) if draw_card: def hq_damage_callback(damage: int): """HQ疲劳伤害回调""" battlefield = self.get_battlefield() if current_player.player_id == 0: hq = battlefield.player1_support.get_hq() else: hq = battlefield.player2_support.get_hq() if hq: actual_damage = hq.take_damage(damage) if self.debug_mode: print(f"{current_player.name} 的HQ受到疲劳伤害: {actual_damage}") # 检查游戏是否结束 if hq.is_destroyed(): self._end_game(1 - current_player.player_id, "HQ被摧毁(疲劳)") drawn_card = current_player.card_manager.draw_card(hq_damage_callback) if self.debug_mode and drawn_card: print(f"{current_player.name} 摸牌: {drawn_card.name}") if self.debug_mode: print(f"回合 {self.current_turn}: {current_player.name} 的回合开始") print(f"Kredits: {current_player.kredits}/{current_player.kredits_slot}") def _update_kredits_system(self): """更新kredits系统""" current_player = self.get_current_player() # 增长kredits槽(最大12) if current_player.kredits_slot < 12: current_player.kredits_slot += 1 # 重置当前kredits为槽数 current_player.kredits = current_player.kredits_slot # 同步战斗引擎的kredits if current_player.player_id == 0: self.battle_engine.player1_kredits_slot = current_player.kredits_slot self.battle_engine.player1_kredits = current_player.kredits else: self.battle_engine.player2_kredits_slot = current_player.kredits_slot self.battle_engine.player2_kredits = current_player.kredits def end_turn(self): """结束当前玩家回合""" if self.phase != GameStatePhase.GAME_ACTIVE: raise ValueError("只能在游戏进行阶段结束回合") current_player = self.get_current_player() if self.debug_mode: print(f"{current_player.name} 结束回合") # 切换到对手 self.active_player_id = 1 - self.active_player_id # 如果切换到先手玩家,增加回合数 if self.active_player_id == self.first_player_id: self.current_turn += 1 # 开始对手回合 self._start_player_turn(draw_card=True) # 同步战斗引擎的状态 self.battle_engine.active_player = self.active_player_id self.battle_engine.current_turn = self.current_turn def _end_game(self, winner_id: int, reason: str): """结束游戏""" self.game_ended = True self.winner_id = winner_id self.end_reason = reason self.phase = GameStatePhase.GAME_ENDED winner = self.get_player(winner_id) if self.debug_mode: print(f"游戏结束!获胜者: {winner.name} ({reason})") def check_win_condition(self): """检查胜利条件""" if self.game_ended: return # 检查HQ是否被摧毁 battlefield = self.get_battlefield() hq1 = battlefield.player1_support.get_hq() if hq1 and hq1.is_destroyed(): self._end_game(1, "摧毁敌方HQ") return hq2 = battlefield.player2_support.get_hq() if hq2 and hq2.is_destroyed(): self._end_game(0, "摧毁敌方HQ") return def get_game_statistics(self) -> Dict[str, Any]: """获取游戏统计信息""" return { 'current_turn': self.current_turn, 'phase': self.phase.name, 'active_player': self.get_current_player().name, 'game_ended': self.game_ended, 'winner': self.get_player(self.winner_id).name if self.winner_id is not None else None, 'end_reason': self.end_reason, 'player1_stats': { 'name': self.player1.name, 'nations': f"{self.player1.major_nation}/{self.player1.minor_nation}", 'kredits': f"{self.player1.kredits}/{self.player1.kredits_slot}", 'card_stats': self.player1.card_manager.get_statistics() }, 'player2_stats': { 'name': self.player2.name, 'nations': f"{self.player2.major_nation}/{self.player2.minor_nation}", 'kredits': f"{self.player2.kredits}/{self.player2.kredits_slot}", 'card_stats': self.player2.card_manager.get_statistics() } }