diff --git a/.tasks/2025-11-03_2_werewolf-game.md b/.tasks/2025-11-03_2_werewolf-game.md index 3fce2a3..9545a2c 100644 --- a/.tasks/2025-11-03_2_werewolf-game.md +++ b/.tasks/2025-11-03_2_werewolf-game.md @@ -275,6 +275,50 @@ if game_type == 'werewolf': - 状态:成功 +[2025-11-07_11:13:56] +- 已修改: + 1. games/werewolf.py - 改进狼人投票机制 + +- 更改: + 1. 在游戏状态数据中添加 wolf_votes 字段,记录每个狼人的投票 + 2. 修改 _wolf_kill() 方法,实现完整的投票流程: + - 记录每个狼人的投票(支持改票) + - 检查是否所有存活狼人都已投票 + - 未全部投票时提示等待其他狼人 + - 全部投票后统计票数 + - 票数唯一时确定目标并推进阶段 + - 平票时清除投票记录并要求重新投票 + 3. 优化投票提示信息,显示投票进度和结果 + +- 原因: + 解决之前"只要一个狼人投票就立即刀人"的问题。 + 现在要求所有狼人都投票,统计票数最多的目标,平票则重新投票,符合狼人杀游戏规则。 + +- 阻碍因素: + 无 + +- 状态:成功 + +[2025-11-07_11:22:53] +- 已修改: + 1. games/werewolf.py - 狼人投票结果保密处理 + +- 更改: + 1. 修改狼人投票反馈机制,不在群里播报投票目标 + 2. 单个狼人投票时,通过私聊确认投票,群消息只显示"投票已记录" + 3. 投票平票时,通过私聊通知狼人具体平票目标,群消息只显示"平票" + 4. 投票完成时,通过私聊通知所有狼人击杀目标,群消息只显示"投票完成" + 5. 所有敏感信息(投票目标、平票详情、击杀决定)均通过私聊发送给狼人 + +- 原因: + 符合狼人杀游戏规则,狼人刀人的决定应该保密,不能在群里公开播报。 + 只有狼人自己知道投票情况和击杀目标,其他玩家在天亮时才知道结果。 + +- 阻碍因素: + 无 + +- 状态:成功 + # 最终审查 待审查阶段完成... diff --git a/games/werewolf.py b/games/werewolf.py index 2d5f31f..e223be8 100644 --- a/games/werewolf.py +++ b/games/werewolf.py @@ -324,6 +324,7 @@ class WerewolfGame(BaseGame): 'round': 0, 'wolves': [], 'kill_target': None, + 'wolf_votes': {}, # 狼人投票记录 {user_id: target_id} 'seer_result': {}, 'witch_save': False, 'witch_poison': None, @@ -723,18 +724,74 @@ class WerewolfGame(BaseGame): if current_phase != 'night_kill': return f"❌ 当前不是狼人行动阶段!当前阶段:{self._get_phase_description(current_phase)['name']}" - # 记录投票 - # 简化:只要有一个狼人投票就算成功 - if state_data.get('kill_target') is None: - state_data['kill_target'] = target_id + # 记录投票(允许改票) + wolf_votes = state_data.get('wolf_votes', {}) + wolf_votes[player['user_id']] = target_id + state_data['wolf_votes'] = wolf_votes + self._save_game_state(chat_id, state_data) + + # 获取所有存活的狼人 + alive_wolves = [] + for p in state_data['players']: + if p['role'] == 'wolf' and p['alive']: + alive_wolves.append(p['user_id']) + + # 检查是否所有狼人都已投票 + voted_wolves = set(wolf_votes.keys()) + all_wolves = set(alive_wolves) + + if not all_wolves.issubset(voted_wolves): + # 还有狼人未投票,私聊通知投票者 + not_voted_count = len(all_wolves - voted_wolves) + vote_confirm_msg = f"## 🐺 投票确认\n\n✅ 你投票给 **{target_id}号玩家**\n\n⏳ 等待其他狼人投票(还有{not_voted_count}个狼人未投票)" + await self._send_to_player(player['user_id'], vote_confirm_msg, sender="系统") + + # 群消息不透露目标 + return f"✅ 投票已记录,等待其他狼人(还有{not_voted_count}个未投票)" + + # 所有狼人都已投票,统计票数 + vote_count = {} + for wolf_id, target in wolf_votes.items(): + if wolf_id in alive_wolves: # 只统计存活狼人的投票 + vote_count[target] = vote_count.get(target, 0) + 1 + + # 找出票数最多的目标 + max_votes = max(vote_count.values()) + top_targets = [tid for tid, count in vote_count.items() if count == max_votes] + + # 判断是否平票 + if len(top_targets) > 1: + # 平票,清除投票记录,要求重新投票 + state_data['wolf_votes'] = {} self._save_game_state(chat_id, state_data) - # 自动推进到下一阶段 - next_phase_msg = self._advance_phase(chat_id, state_data) + # 私聊通知所有狼人平票结果 + targets_str = '、'.join([f"{tid}号" for tid in top_targets]) + for p in state_data['players']: + if p['role'] == 'wolf' and p['alive']: + tie_msg = f"## 🐺 狼人投票结果\n\n⚠️ 投票结果平票!\n\n票数最多的玩家:{targets_str}(各{max_votes}票)\n\n请重新投票" + await self._send_to_player(p['user_id'], tie_msg, sender="系统") - return f"✅ 投票成功:刀{target_id}号玩家{next_phase_msg}" - else: - return f"⚠️ 今晚已经有了投票目标:{state_data['kill_target']}号" + # 群消息不透露具体目标 + return f"⚠️ 狼人投票结果平票,请重新投票" + + # 票数唯一,确定击杀目标 + kill_target = top_targets[0] + state_data['kill_target'] = kill_target + state_data['wolf_votes'] = {} # 清空投票记录 + self._save_game_state(chat_id, state_data) + + # 私聊通知所有狼人投票结果 + for p in state_data['players']: + if p['role'] == 'wolf' and p['alive']: + vote_msg = f"## 🐺 狼人投票结果\n\n✅ 投票完成:决定刀 **{kill_target}号玩家**({max_votes}票)" + await self._send_to_player(p['user_id'], vote_msg, sender="系统") + + # 自动推进到下一阶段 + next_phase_msg = self._advance_phase(chat_id, state_data) + + # 群消息不透露击杀目标 + return f"✅ 狼人投票完成{next_phase_msg}" async def _seer_check(self, chat_id: int, state_data: Dict, player: Dict, target_id: int) -> str: """预言家验人