diff --git a/games/werewolf.py b/games/werewolf.py index 2954af7..aaefd66 100644 --- a/games/werewolf.py +++ b/games/werewolf.py @@ -278,7 +278,11 @@ class WerewolfGame(BaseGame): # 更新阶段 state_data['phase'] = next_phase - self._save_game_state(chat_id, state_data) + day_intro_msg = "" + if next_phase == 'day_discuss': + day_intro_msg = self._resolve_night_results(chat_id, state_data) + else: + self._save_game_state(chat_id, state_data) # 如果进入女巫阶段,且女巫有解药,通知女巫刀人情况 if next_phase == 'night_witch': @@ -311,8 +315,109 @@ class WerewolfGame(BaseGame): msg += f"👤 {next_phase_desc['role']}请行动:\n" msg += f"{next_phase_desc['instruction']}" + if day_intro_msg: + msg = f"{day_intro_msg}{msg}" + return msg + def _resolve_night_results(self, chat_id: int, state_data: Dict) -> str: + """结算夜晚结果并生成白天播报 + + Args: + chat_id: 会话ID + state_data: 游戏状态 + + Returns: + 白天播报文本 + """ + players = state_data.get('players', []) + deaths_info: List[Dict[str, Any]] = [] + + kill_target = state_data.get('kill_target') + witch_saved = state_data.get('witch_save', False) + witch_poison_target = state_data.get('witch_poison') + + def _find_player_by_id(pid: int) -> Optional[Dict[str, Any]]: + for p in players: + if p.get('id') == pid: + return p + return None + + # 狼人击杀(0表示空刀) + if kill_target and kill_target != 0 and not witch_saved: + killed_player = _find_player_by_id(kill_target) + if killed_player and killed_player.get('alive', True): + killed_player['alive'] = False + deaths_info.append({ + 'id': killed_player.get('id'), + 'name': killed_player.get('name'), + 'reason': 'wolf' + }) + + # 女巫毒人 + if witch_poison_target: + poisoned_player = _find_player_by_id(witch_poison_target) + if poisoned_player and poisoned_player.get('alive', True): + poisoned_player['alive'] = False + if not any(d.get('id') == poisoned_player.get('id') for d in deaths_info): + deaths_info.append({ + 'id': poisoned_player.get('id'), + 'name': poisoned_player.get('name'), + 'reason': 'poison' + }) + else: + for death in deaths_info: + if death.get('id') == poisoned_player.get('id'): + death['reason'] = 'wolf_poison' + break + + # 保存夜晚死亡名单 + state_data['night_deaths'] = deaths_info + + # 重置夜晚临时状态 + state_data['kill_target'] = None + state_data['witch_save'] = False + state_data['witch_poison'] = None + state_data['wolf_votes'] = {} + + # TODO: 如有胜负判定逻辑,可在此调用 + + self._save_game_state(chat_id, state_data) + + return self._build_day_intro_message(state_data) + + def _build_day_intro_message(self, state_data: Dict) -> str: + """构建白天播报消息 + + Args: + state_data: 游戏状态 + + Returns: + 播报文本 + """ + deaths = state_data.get('night_deaths') or [] + + message = "\n\n---\n\n## ☀️ 昨夜情况\n\n" + + if not deaths: + message += "✨ 昨夜平安,没有玩家死亡。\n" + return message + + message += "⚠️ 昨夜死亡名单:\n\n" + reason_map = { + 'wolf': "被狼人击杀", + 'poison': "被女巫毒杀", + 'wolf_poison': "遭遇狼人击杀且被女巫再次毒杀" + } + + for death in deaths: + player_name = death.get('name') or "未知玩家" + player_id = death.get('id') + reason = reason_map.get(death.get('reason'), "死亡") + message += f"- {player_id}号 {player_name}({reason})\n" + + return message + def _open_game(self, chat_id: int, user_id: int) -> str: """主持人开房 @@ -348,7 +453,8 @@ class WerewolfGame(BaseGame): 'day_dead': [], 'vote_targets': {}, 'discussed': False, - 'wolf_know_each_other': False + 'wolf_know_each_other': False, + 'night_deaths': [] } self._save_game_state(chat_id, state_data)