"""问答游戏""" import json import random import logging from pathlib import Path from games.base import BaseGame from utils.parser import CommandParser logger = logging.getLogger(__name__) class QuizGame(BaseGame): """问答游戏""" def __init__(self): """初始化游戏""" super().__init__() self._questions = None def _load_questions(self): """懒加载题库""" if self._questions is None: try: data_file = Path(__file__).parent.parent / "data" / "quiz.json" with open(data_file, 'r', encoding='utf-8') as f: data = json.load(f) self._questions = data.get('questions', []) logger.info(f"题库加载完成,共 {len(self._questions)} 道题") except Exception as e: logger.error(f"加载题库失败: {e}") self._questions = [] async def handle(self, command: str, chat_id: int, user_id: int) -> str: """处理问答指令 Args: command: 指令,如 ".quiz" 或 ".quiz 答案" chat_id: 会话ID user_id: 用户ID Returns: 回复消息 """ try: # 加载题库 self._load_questions() if not self._questions: return "❌ 题库加载失败" # 提取参数 _, args = CommandParser.extract_command_args(command) args = args.strip() # 检查是否有进行中的题目 state = self.db.get_game_state(chat_id, user_id, 'quiz') if not args: # 没有参数,出新题或显示当前题 if state: # 显示当前题目 state_data = state['state_data'] return self._show_current_question(state_data) else: # 出新题 return self._new_question(chat_id, user_id) else: # 有参数,检查答案 if state: return self._check_answer(chat_id, user_id, args) else: # 没有进行中的题目 return "⚠️ 当前没有题目,输入 `.quiz` 获取新题目" except Exception as e: logger.error(f"处理问答指令错误: {e}", exc_info=True) return f"❌ 处理指令出错: {str(e)}" def _new_question(self, chat_id: int, user_id: int) -> str: """出新题目 Args: chat_id: 会话ID user_id: 用户ID Returns: 题目信息 """ # 随机选择一道题 question = random.choice(self._questions) # 保存游戏状态 state_data = { 'question_id': question['id'], 'question': question['question'], 'answer': question['answer'], 'keywords': question['keywords'], 'hint': question.get('hint', ''), 'category': question.get('category', ''), 'attempts': 0, 'max_attempts': 3 } self.db.save_game_state(chat_id, user_id, 'quiz', state_data) # 格式化输出 text = f"## 📝 问答题\n\n" text += f"**分类**:{question.get('category', '未分类')}\n\n" text += f"**问题**:{question['question']}\n\n" text += f"💡 你有 **3** 次回答机会\n\n" text += f"输入 `.quiz 答案` 来回答" return text def _show_current_question(self, state_data: dict) -> str: """显示当前题目 Args: state_data: 游戏状态数据 Returns: 题目信息 """ attempts = state_data['attempts'] max_attempts = state_data['max_attempts'] remaining = max_attempts - attempts text = f"## 📝 当前题目\n\n" text += f"**分类**:{state_data.get('category', '未分类')}\n\n" text += f"**问题**:{state_data['question']}\n\n" text += f"**剩余机会**:{remaining} 次\n\n" # 如果已经尝试过,显示提示 if attempts > 0 and state_data.get('hint'): text += f"💡 提示:{state_data['hint']}\n\n" text += f"输入 `.quiz 答案` 来回答" return text def _check_answer(self, chat_id: int, user_id: int, user_answer: str) -> str: """检查答案 Args: chat_id: 会话ID user_id: 用户ID user_answer: 用户答案 Returns: 结果信息 """ state = self.db.get_game_state(chat_id, user_id, 'quiz') if not state: return "⚠️ 当前没有题目" state_data = state['state_data'] correct_answer = state_data['answer'] keywords = state_data['keywords'] attempts = state_data['attempts'] max_attempts = state_data['max_attempts'] # 更新尝试次数 attempts += 1 # 检查答案(关键词匹配) user_answer_lower = user_answer.lower().strip() is_correct = False for keyword in keywords: if keyword.lower() in user_answer_lower: is_correct = True break if is_correct: # 回答正确 self.db.delete_game_state(chat_id, user_id, 'quiz') self.db.update_game_stats(user_id, 'quiz', win=True) text = f"## 🎉 回答正确!\n\n" text += f"**答案**:{correct_answer}\n\n" text += f"**用了**:{attempts} 次机会\n\n" if attempts == 1: text += "太棒了!一次就答对!🎯" else: text += "虽然用了几次机会,但最终还是答对了!💪" text += "\n\n输入 `.quiz` 获取下一题" return text # 回答错误 if attempts >= max_attempts: # 机会用完 self.db.delete_game_state(chat_id, user_id, 'quiz') self.db.update_game_stats(user_id, 'quiz', loss=True) text = f"## ❌ 很遗憾,答错了\n\n" text += f"**正确答案**:{correct_answer}\n\n" text += "下次加油!\n\n" text += "输入 `.quiz` 获取下一题" return text # 还有机会 state_data['attempts'] = attempts self.db.save_game_state(chat_id, user_id, 'quiz', state_data) remaining = max_attempts - attempts text = f"## ❌ 答案不对\n\n" text += f"**你的答案**:{user_answer}\n\n" text += f"**剩余机会**:{remaining} 次\n\n" # 显示提示 if state_data.get('hint'): text += f"💡 提示:{state_data['hint']}\n\n" text += "再想想,继续回答吧!" return text def get_help(self) -> str: """获取帮助信息""" return """## 📝 问答游戏 ### 基础用法 - `.quiz` - 获取新题目 - `.quiz 答案` - 回答问题 ### 游戏规则 - 每道题有 3 次回答机会 - 答错会显示提示 - 回答正确可继续下一题 ### 示例 ``` .quiz # 获取题目 .quiz Python # 回答 .quiz 北京 # 回答 ``` 💡 提示:题目涵盖编程、地理、常识等多个领域 """