diff --git a/.tasks/2025-11-03_2_werewolf-game.md b/.tasks/2025-11-03_2_werewolf-game.md index d5466cf..b6b5741 100644 --- a/.tasks/2025-11-03_2_werewolf-game.md +++ b/.tasks/2025-11-03_2_werewolf-game.md @@ -209,37 +209,29 @@ if game_type == 'werewolf': - 状态:成功 +[2025-11-04_17:41:14] +- 已修改: + 1. games/werewolf.py - 改进阶段提示和自动流转功能 + +- 更改: + 1. 添加阶段名称映射系统(phase_configs),定义各阶段的中文名称、行动角色和指令说明 + 2. 实现阶段管理方法:_get_phase_description()、_get_next_phase()、_advance_phase() + 3. 改进游戏开始提示,明确显示"第一夜 - 狼人行动阶段"和操作指令 + 4. 实现自动阶段流转:狼人刀人后自动进入预言家阶段,预言家验人后自动进入女巫阶段 + 5. 新增女巫跳过功能:支持`.werewolf 跳过`指令,女巫可以选择不行动 + 6. 改进状态显示:_show_status()现在显示中文阶段名称、当前行动角色和操作指令 + 7. 更新身份说明和帮助信息,添加女巫跳过选项说明 + 8. 各技能方法添加阶段验证,确保在正确的阶段使用技能 + +- 原因: + 解决用户反馈的游戏阶段不明显的问题,让玩家清楚知道当前是什么阶段、谁应该行动、下一步是什么阶段 + +- 阻碍因素: + 无 + +- 状态:成功 + # 最终审查 -## 实施总结 -本次任务成功实现了狼人杀游戏系统的核心功能: - -1. **游戏管理**:开房、加入、开始、状态查询、结束 -2. **身份系统**:自动分配角色,狼人互相认识 -3. **私聊功能**:单聊、狼人群聊、发送者标识 -4. **技能系统**:狼人刀人、预言家验人、女巫用药 -5. **数据持久化**:使用game_states表存储状态 - -## 技术特点 -- 继承BaseGame基类,符合现有架构 -- 使用user_id=0存储群级别状态 -- 充分利用现有私聊功能 -- 完整的帮助和错误提示 -- 合理的技能使用限制 - -## 后续可扩展功能 -- 自动阶段流转(天黑/天亮) -- 投票放逐系统 -- 胜负自动判断 -- 游戏历史记录 -- 统计功能 - -## 测试建议 -1. 测试开房、加入、开始流程 -2. 测试身份分配和私聊通知 -3. 测试私聊和狼人群聊功能 -4. 测试所有技能使用 -5. 测试多人游戏(6-12人) - -实施与计划完全匹配 +待审查阶段完成... diff --git a/games/werewolf.py b/games/werewolf.py index d966353..192071c 100644 --- a/games/werewolf.py +++ b/games/werewolf.py @@ -26,6 +26,30 @@ class WerewolfGame(BaseGame): } self.min_players = 6 self.max_players = 12 + + # 阶段名称映射:{阶段代码: {'name': 中文名称, 'role': 行动角色, 'instruction': 指令说明}} + self.phase_configs = { + 'night_kill': { + 'name': '狼人行动阶段', + 'role': '狼人', + 'instruction': '使用 `.werewolf 杀 ` 投票杀人' + }, + 'night_seer': { + 'name': '预言家验人阶段', + 'role': '预言家', + 'instruction': '使用 `.werewolf 验 ` 查验身份' + }, + 'night_witch': { + 'name': '女巫行动阶段', + 'role': '女巫', + 'instruction': '使用 `.werewolf 救 ` 救人、`.werewolf 毒 ` 毒人,或 `.werewolf 跳过` 不行动' + }, + 'day_discuss': { + 'name': '白天讨论阶段', + 'role': '所有玩家', + 'instruction': '讨论昨晚的事件' + } + } async def handle(self, command: str, chat_id: int, user_id: int) -> str: """处理狼人杀指令 @@ -86,6 +110,10 @@ class WerewolfGame(BaseGame): except ValueError: pass + # 女巫跳过指令 + if action in ['跳过', 'pass']: + return await self._witch_pass(chat_id, user_id) + # 技能指令 if action in ['杀', '验', '救', '毒', '守']: if len(parts) < 2: @@ -131,6 +159,78 @@ class WerewolfGame(BaseGame): """ self.db.save_game_state(chat_id, 0, 'werewolf', state_data) + def _get_phase_description(self, phase: str) -> Dict[str, str]: + """获取阶段描述信息 + + Args: + phase: 阶段代码 + + Returns: + 阶段描述字典,包含name、role、instruction + """ + return self.phase_configs.get(phase, { + 'name': phase, + 'role': '未知', + 'instruction': '' + }) + + def _get_next_phase(self, current_phase: str) -> Optional[str]: + """获取下一阶段 + + Args: + current_phase: 当前阶段代码 + + Returns: + 下一阶段代码,如果无下一阶段则返回None + """ + phase_sequence = ['night_kill', 'night_seer', 'night_witch', 'day_discuss'] + try: + current_index = phase_sequence.index(current_phase) + if current_index < len(phase_sequence) - 1: + return phase_sequence[current_index + 1] + except ValueError: + pass + return None + + def _advance_phase(self, chat_id: int, state_data: Dict) -> str: + """推进到下一阶段 + + Args: + chat_id: 会话ID + state_data: 游戏状态 + + Returns: + 阶段推进提示消息 + """ + current_phase = state_data.get('phase') + if not current_phase: + return "" + + next_phase = self._get_next_phase(current_phase) + if not next_phase: + return "" + + # 更新阶段 + state_data['phase'] = next_phase + self._save_game_state(chat_id, state_data) + + # 获取下一阶段描述 + next_phase_desc = self._get_phase_description(next_phase) + + # 构建提示消息 + round_num = state_data.get('round', 1) + if next_phase.startswith('night'): + time_desc = "夜晚" + else: + time_desc = "白天" + + msg = f"\n\n---\n\n## 🌙 进入下一阶段\n\n" + msg += f"**{time_desc} - {next_phase_desc['name']}**\n\n" + msg += f"👤 {next_phase_desc['role']}请行动:\n" + msg += f"{next_phase_desc['instruction']}" + + return msg + def _open_game(self, chat_id: int, user_id: int) -> str: """主持人开房 @@ -296,8 +396,16 @@ class WerewolfGame(BaseGame): # 私聊发送身份 await self._send_identities(chat_id, state_data) + # 获取当前阶段描述 + phase_desc = self._get_phase_description('night_kill') + # 公共消息 - return f"## 🎮 游戏开始!\n\n玩家已分配身份,请查看私聊消息\n\n第一夜,天黑请闭眼..." + msg = f"## 🎮 游戏开始!\n\n玩家已分配身份,请查看私聊消息\n\n" + msg += f"---\n\n## 🌙 第一夜 - {phase_desc['name']}\n\n" + msg += f"🐺 **{phase_desc['role']}请行动**:\n" + msg += f"{phase_desc['instruction']}" + + return msg async def _send_identities(self, chat_id: int, state_data: Dict): """发送身份信息到私聊 @@ -316,7 +424,7 @@ class WerewolfGame(BaseGame): role_details = { 'wolf': '你的技能:\n- 每晚可以投票决定杀死一个目标\n- 你认识所有狼人同伴\n- 胜利条件:杀死所有神职和平民\n\n使用 `.werewolf 杀 ` 投票杀人', 'seer': '你的技能:\n- 每晚可以查验一个玩家的身份\n- 胜利条件:消灭所有狼人\n\n使用 `.werewolf 验 ` 查验身份', - 'witch': '你的技能:\n- 拥有一瓶解药和一瓶毒药\n- 每晚可以救人(只能使用一次)或毒人(只能使用一次)\n- 胜利条件:消灭所有狼人\n\n使用 `.werewolf 救 ` 救人\n使用 `.werewolf 毒 ` 毒人', + 'witch': '你的技能:\n- 拥有一瓶解药和一瓶毒药\n- 每晚可以救人(只能使用一次)或毒人(只能使用一次)\n- 也可以选择跳过不行动\n- 胜利条件:消灭所有狼人\n\n使用 `.werewolf 救 ` 救人\n使用 `.werewolf 毒 ` 毒人\n使用 `.werewolf 跳过` 不行动', 'civilian': '你没有特殊技能\n\n你的胜利条件:消灭所有狼人\n\n仔细观察,通过投票帮助好人阵营获胜' } @@ -534,12 +642,20 @@ class WerewolfGame(BaseGame): if not target['alive']: return f"❌ {target_id}号玩家已死亡!" + # 检查当前阶段 + 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 self._save_game_state(chat_id, state_data) - return f"✅ 投票成功:刀{target_id}号玩家" + + # 自动推进到下一阶段 + next_phase_msg = self._advance_phase(chat_id, state_data) + + return f"✅ 投票成功:刀{target_id}号玩家{next_phase_msg}" else: return f"⚠️ 今晚已经有了投票目标:{state_data['kill_target']}号" @@ -562,6 +678,10 @@ class WerewolfGame(BaseGame): if not current_phase or not current_phase.startswith('night'): return "❌ 只能在夜晚使用技能!" + # 检查当前阶段 + if current_phase != 'night_seer': + return f"❌ 当前不是预言家验人阶段!当前阶段:{self._get_phase_description(current_phase)['name']}" + # 查找目标 target = None for p in state_data['players']: @@ -582,7 +702,10 @@ class WerewolfGame(BaseGame): msg = f"## 🔮 验人结果\n\n{target_id}号玩家的身份是:**{result_text}**" await self._send_to_player(player['user_id'], msg, sender="系统") - return f"✅ 验人成功!已私聊发送结果" + # 自动推进到下一阶段 + next_phase_msg = self._advance_phase(chat_id, state_data) + + return f"✅ 验人成功!已私聊发送结果{next_phase_msg}" async def _witch_save(self, chat_id: int, state_data: Dict, player: Dict, target_id: int) -> str: """女巫救人 @@ -606,6 +729,10 @@ class WerewolfGame(BaseGame): if not current_phase or not current_phase.startswith('night'): return "❌ 只能在夜晚使用技能!" + # 检查当前阶段 + if current_phase != 'night_witch': + return f"❌ 当前不是女巫行动阶段!当前阶段:{self._get_phase_description(current_phase)['name']}" + # 查找目标 target = None for p in state_data['players']: @@ -620,7 +747,10 @@ class WerewolfGame(BaseGame): state_data['witch_save'] = True self._save_game_state(chat_id, state_data) - return f"✅ 救人成功:救了{target_id}号玩家" + # 自动推进到下一阶段 + next_phase_msg = self._advance_phase(chat_id, state_data) + + return f"✅ 救人成功:救了{target_id}号玩家{next_phase_msg}" async def _witch_poison(self, chat_id: int, state_data: Dict, player: Dict, target_id: int) -> str: """女巫毒人 @@ -644,6 +774,10 @@ class WerewolfGame(BaseGame): if not current_phase or not current_phase.startswith('night'): return "❌ 只能在夜晚使用技能!" + # 检查当前阶段 + if current_phase != 'night_witch': + return f"❌ 当前不是女巫行动阶段!当前阶段:{self._get_phase_description(current_phase)['name']}" + # 查找目标 target = None for p in state_data['players']: @@ -661,7 +795,52 @@ class WerewolfGame(BaseGame): state_data['witch_poison'] = target_id self._save_game_state(chat_id, state_data) - return f"✅ 毒人成功:毒了{target_id}号玩家" + # 自动推进到下一阶段 + next_phase_msg = self._advance_phase(chat_id, state_data) + + return f"✅ 毒人成功:毒了{target_id}号玩家{next_phase_msg}" + + async def _witch_pass(self, chat_id: int, user_id: int) -> str: + """女巫跳过(不行动) + + Args: + chat_id: 会话ID + user_id: 用户ID + + Returns: + 提示消息 + """ + state_data = self._get_game_state(chat_id) + if not state_data: + return "❌ 没有正在进行的游戏!" + + if state_data['status'] != 'playing': + return "❌ 游戏未开始或已结束!" + + # 查找玩家 + player = None + for p in state_data['players']: + if p['user_id'] == user_id: + player = p + break + + if not player: + return "❌ 你不是游戏参与者!" + + if player['role'] != 'witch': + return "❌ 只有女巫可以跳过!" + + if not player['alive']: + return "❌ 死亡玩家无法使用技能!" + + current_phase = state_data['phase'] + if current_phase != 'night_witch': + return f"❌ 当前不是女巫行动阶段!当前阶段:{self._get_phase_description(current_phase)['name']}" + + # 自动推进到下一阶段 + next_phase_msg = self._advance_phase(chat_id, state_data) + + return f"✅ 女巫选择跳过,不行动{next_phase_msg}" def _show_status(self, chat_id: int) -> str: """显示游戏状态 @@ -683,11 +862,18 @@ class WerewolfGame(BaseGame): if status != 'playing': return "❌ 游戏未开始或已结束!" + # 获取当前阶段描述 + current_phase = state_data.get('phase', 'unknown') + phase_desc = self._get_phase_description(current_phase) + # 显示玩家状态(只显示存活状态,不显示身份) msg = f"## 🎮 游戏进行中\n\n" - msg += f"回合:第{state_data['round']}回合\n" - msg += f"阶段:{state_data['phase']}\n\n" - msg += f"**玩家状态**:\n" + msg += f"**回合**:第{state_data['round']}回合\n" + msg += f"**当前阶段**:{phase_desc['name']}\n" + msg += f"**行动角色**:{phase_desc['role']}\n" + if phase_desc['instruction']: + msg += f"**操作指令**:{phase_desc['instruction']}\n" + msg += f"\n**玩家状态**:\n" alive_count = 0 dead_count = 0 @@ -752,6 +938,7 @@ class WerewolfGame(BaseGame): - `.werewolf 验 ` - 预言家验人 - `.werewolf 救 ` - 女巫救人 - `.werewolf 毒 ` - 女巫毒人 +- `.werewolf 跳过` - 女巫跳过(不行动) ### 游戏规则 **人数配置**: