""" 卡牌管理器 - 管理手牌、抽牌堆、弃牌堆 """ from typing import List, Optional, Set import random from collections import deque from .card import BaseCard from .deck import Deck class CardManager: """卡牌管理器 - 管理单个玩家的所有卡牌状态""" def __init__(self, deck: Deck): self.deck = deck # 抽牌堆 - 使用deque提高性能 self.draw_pile: deque = deque(deck.get_deck_cards()) # 手牌 self.hand: List[BaseCard] = [] # 弃牌堆 self.discard_pile: List[BaseCard] = [] # 疲劳系统 self.fatigue_damage = 1 # 当前疲劳伤害 self.total_fatigue_taken = 0 # 总疲劳伤害 # 战略调度标记 self.strategic_deployment_completed = False # 手牌大小限制(如果有的话) self.max_hand_size = 10 # 默认最大手牌数 # 洗牌抽牌堆 self.shuffle_draw_pile() def shuffle_draw_pile(self): """洗牌抽牌堆""" draw_list = list(self.draw_pile) random.shuffle(draw_list) self.draw_pile = deque(draw_list) def draw_card(self, hq_defense_callback: callable = None) -> Optional[BaseCard]: """ 抽一张牌 如果抽牌堆为空,对HQ造成疲劳伤害 Args: hq_defense_callback: HQ受伤回调函数,接收伤害值作为参数 Returns: 抽到的卡牌,如果抽牌堆为空且造成疲劳伤害则返回None """ if self.draw_pile: # 正常抽牌 card = self.draw_pile.popleft() self.hand.append(card) return card else: # 抽牌堆为空,造成疲劳伤害 if hq_defense_callback: hq_defense_callback(self.fatigue_damage) self.total_fatigue_taken += self.fatigue_damage self.fatigue_damage += 1 # 疲劳伤害递增 return None def draw_multiple_cards(self, count: int, hq_defense_callback: callable = None) -> List[BaseCard]: """ 抽多张牌 Args: count: 要抽的牌数 hq_defense_callback: HQ受伤回调函数 Returns: 成功抽到的卡牌列表 """ drawn_cards = [] for _ in range(count): card = self.draw_card(hq_defense_callback) if card: drawn_cards.append(card) return drawn_cards def initial_draw(self, count: int) -> List[BaseCard]: """ 初始摸牌(不会触发疲劳伤害) Args: count: 要抽的牌数 Returns: 抽到的卡牌列表 """ drawn_cards = [] for _ in range(min(count, len(self.draw_pile))): if self.draw_pile: card = self.draw_pile.popleft() self.hand.append(card) drawn_cards.append(card) return drawn_cards def play_card_from_hand(self, card: BaseCard) -> bool: """ 从手牌打出一张卡 Args: card: 要打出的卡牌 Returns: 是否成功从手牌移除 """ if card in self.hand: self.hand.remove(card) return True return False def discard_card(self, card: BaseCard): """将卡牌放入弃牌堆""" self.discard_pile.append(card) def discard_from_hand(self, card: BaseCard) -> bool: """ 从手牌弃置一张卡 Args: card: 要弃置的卡牌 Returns: 是否成功弃置 """ if card in self.hand: self.hand.remove(card) self.discard_card(card) return True return False def strategic_deployment(self, cards_to_mulligan: List[BaseCard]) -> List[BaseCard]: """ 战略调度 - 重新抽取不想要的卡牌 Args: cards_to_mulligan: 要重抽的卡牌列表 Returns: 新抽到的卡牌列表 """ if self.strategic_deployment_completed: raise ValueError("战略调度已经完成,不能重复进行") # 验证所有卡牌都在手牌中 for card in cards_to_mulligan: if card not in self.hand: raise ValueError(f"卡牌 {card.name} 不在手牌中") # 移除要重抽的卡牌 for card in cards_to_mulligan: self.hand.remove(card) # 将这些卡牌放回抽牌堆 for card in cards_to_mulligan: self.draw_pile.append(card) # 重新洗牌 self.shuffle_draw_pile() # 抽取相同数量的新卡 new_cards = [] for _ in range(len(cards_to_mulligan)): if self.draw_pile: card = self.draw_pile.popleft() self.hand.append(card) new_cards.append(card) self.strategic_deployment_completed = True return new_cards def can_draw_safely(self) -> bool: """检查是否可以安全抽牌(不会触发疲劳)""" return len(self.draw_pile) > 0 def cards_remaining_in_deck(self) -> int: """返回抽牌堆剩余卡牌数量""" return len(self.draw_pile) def hand_size(self) -> int: """返回当前手牌数量""" return len(self.hand) def is_hand_full(self) -> bool: """检查手牌是否已满""" return len(self.hand) >= self.max_hand_size def get_hand_copy(self) -> List[BaseCard]: """获取手牌的副本""" return self.hand.copy() def get_card_in_hand_by_name(self, name: str) -> Optional[BaseCard]: """根据名称在手牌中查找卡牌""" for card in self.hand: if card.name == name: return card return None def get_playable_cards(self, current_kredits: int) -> List[BaseCard]: """ 获取当前可以打出的卡牌(基于费用) Args: current_kredits: 当前可用的kredits Returns: 可以打出的卡牌列表 """ playable = [] for card in self.hand: if card.stats.cost <= current_kredits: playable.append(card) return playable def reshuffle_discard_into_deck(self): """ 将弃牌堆重新洗入抽牌堆 这个功能可能在某些特殊卡牌效果中使用 """ if self.discard_pile: # 将弃牌堆的卡牌加入抽牌堆 for card in self.discard_pile: self.draw_pile.append(card) # 清空弃牌堆 self.discard_pile.clear() # 重新洗牌 self.shuffle_draw_pile() def get_statistics(self) -> dict: """获取卡牌管理器统计信息""" return { 'hand_size': len(self.hand), 'cards_in_deck': len(self.draw_pile), 'cards_in_discard': len(self.discard_pile), 'fatigue_damage': self.fatigue_damage, 'total_fatigue_taken': self.total_fatigue_taken, 'strategic_deployment_used': self.strategic_deployment_completed, 'max_hand_size': self.max_hand_size }