Files
WPSBot/.tasks/2025-10-28_1_add-idiom-chain-game.md

8.3 KiB
Raw Blame History

背景

文件名2025-10-28_1_add-idiom-chain-game.md 创建于2025-10-28_15:43:00 创建者admin 主分支main 任务分支task/add-idiom-chain-game_2025-10-28_1 Yolo模式Off

任务描述

在WPS Bot Game项目中新增一个成语接龙游戏功能。

核心需求

  1. 群内多人游戏,机器人作为裁判和出题者
  2. 允许按拼音接龙(包括谐音接龙)
  3. 没有时间限制
  4. 不需要提示功能
  5. 游戏记录保存到.stats统计中
  6. 不允许重复使用成语
  7. 不需要难度分级(非人机对战)
  8. 需要裁判指令用于接受/拒绝玩家回答

游戏玩法

  • 机器人出题(给出起始成语)
  • 群内玩家轮流接龙
  • 机器人判断接龙是否有效(拼音/谐音匹配、未重复使用)
  • 裁判可以手动接受或拒绝某个回答
  • 记录每个玩家的成功接龙次数

项目概览

项目结构

WPSBotGame/
├── app.py                    # FastAPI主应用
├── config.py                 # 配置管理
├── core/
│   ├── database.py          # SQLite数据库操作
│   ├── middleware.py        # 中间件
│   └── models.py            # 数据模型
├── games/                   # 游戏模块
│   ├── base.py             # 游戏基类
│   ├── dice.py             # 骰娘游戏
│   ├── rps.py              # 石头剪刀布
│   ├── fortune.py          # 运势占卜
│   ├── guess.py            # 猜数字
│   └── quiz.py             # 问答游戏
├── data/                   # 数据文件
│   ├── bot.db             # SQLite数据库
│   ├── quiz.json          # 问答题库
│   └── fortunes.json      # 运势数据
├── routers/               # 路由处理
│   ├── callback.py       # WPS回调处理
│   └── health.py         # 健康检查
└── utils/                # 工具模块
    ├── message.py        # 消息发送
    ├── parser.py         # 指令解析
    └── rate_limit.py     # 限流控制

技术栈

  • FastAPIWeb框架
  • SQLite数据存储
  • WPS协作机器人API消息接收与发送

现有游戏架构

  1. 所有游戏继承BaseGame基类
  2. 必须实现handle(command, chat_id, user_id)方法处理指令
  3. 必须实现get_help()方法返回帮助信息
  4. 游戏状态存储在数据库game_states表:(chat_id, user_id, game_type)作为联合主键
  5. 游戏统计存储在game_stats表:记录wins, losses, draws, total_plays
  6. 指令通过CommandParser解析,在callback.py中分发到对应游戏处理器

数据库设计

game_states表

  • chat_id: 会话ID
  • user_id: 用户ID
  • game_type: 游戏类型
  • state_data: JSON格式的游戏状态数据
  • created_at/updated_at: 时间戳

game_stats表

  • user_id: 用户ID
  • game_type: 游戏类型
  • wins/losses/draws/total_plays: 统计数据

分析

关键技术挑战

1. 群级别vs个人级别状态管理

现有游戏(猜数字、问答)都是个人独立状态,使用(chat_id, user_id, game_type)作为主键。

成语接龙是群内共享游戏,需要:

  • 群级别的游戏状态:当前成语、已用成语列表、接龙长度、当前轮到谁
  • 个人级别的统计:每个玩家的成功接龙次数

可能方案:

  • 使用特殊user_id如0或-1存储群级别游戏状态
  • 或者在state_data中存储所有玩家信息

2. 成语词库准备

需要准备:

  • 成语列表至少500-1000个常用成语
  • 每个成语的拼音信息(用于判断接龙是否匹配)
  • 数据格式JSON文件类似quiz.json

3. 拼音匹配逻辑

  • 需要拼音库支持pypinyin
  • 支持谐音匹配(声母韵母匹配)
  • 处理多音字情况

4. 裁判指令设计

需要额外指令:

  • .idiom accept - 接受上一个回答
  • .idiom reject - 拒绝上一个回答
  • 需要权限控制(谁可以当裁判?)

5. 游戏流程设计

1. 开始游戏:.idiom start
   - 机器人随机给出起始成语
   - 创建群级别游戏状态
   
2. 玩家接龙:.idiom [成语]
   - 检查是否在词库中
   - 检查拼音是否匹配(首字拼音 == 上一个成语尾字拼音)
   - 检查是否已使用过
   - 自动判断或等待裁判确认
   
3. 裁判操作:.idiom accept/reject
   - 手动接受或拒绝最近的回答
   
4. 查看状态:.idiom status
   - 显示当前成语、已用成语数量、参与人数
   
5. 结束游戏:.idiom stop
   - 显示统计信息
   - 更新每个玩家的game_stats

现有代码分析

CommandParser (utils/parser.py)

需要添加成语接龙指令映射:

'.idiom': 'idiom',
'.成语接龙': 'idiom',

callback.py (routers/callback.py)

需要在handle_command函数中添加idiom游戏分支

if game_type == 'idiom':
    from games.idiom import IdiomGame
    game = IdiomGame()
    return await game.handle(command, chat_id, user_id)

base.py (games/base.py)

需要更新get_help_message()get_stats_message(),添加成语接龙信息。

config.py

可能需要添加成语接龙相关配置:

"idiom": {
    "auto_judge": True,  # 是否自动判断
    "require_approval": False,  # 是否需要裁判确认
}

提议的解决方案

待INNOVATE模式填写

当前执行步骤:"1. 创建任务文件"

任务进度

[2025-10-28 15:45:00]

  • 已修改requirements.txt, config.py, utils/parser.py, routers/callback.py, games/base.py
  • 已创建games/idiom.py
  • 更改:
    1. 在requirements.txt中添加pypinyin==0.51.0依赖
    2. 在config.py的GAME_CONFIG中添加idiom配置起始成语池、历史显示数量
    3. 在utils/parser.py的COMMAND_MAP中添加.idiom、.成语接龙、.成语指令映射
    4. 创建games/idiom.py实现完整的成语接龙游戏逻辑
      • IdiomGame类继承BaseGame
      • 实现handle()主指令分发方法
      • 实现_start_game()开始游戏
      • 实现_make_chain()玩家接龙
      • 实现_set_next_user()指定下一位
      • 实现_reject_idiom()裁判拒绝
      • 实现_show_status()显示状态
      • 实现_show_blacklist()显示黑名单
      • 实现_stop_game()结束游戏
      • 实现_get_pinyin()获取拼音(支持多音字)
      • 实现_check_pinyin_match()检查拼音匹配(忽略声调)
      • 实现_parse_mentioned_user()解析@用户
      • 实现_can_answer()权限检查(防连续、指定轮次)
      • 实现_validate_idiom()词语验证4字、拼音匹配、未使用、未黑名单
      • 实现get_help()帮助信息
    5. 在routers/callback.py的handle_command()中添加idiom游戏分支
    6. 在games/base.py的get_help_message()中添加成语接龙帮助信息
    7. 在games/base.py的get_stats_message()的game_names字典中添加idiom映射
  • 原因:实现成语接龙游戏功能的所有核心代码
  • 阻碍因素:无
  • 状态:未确认

[2025-10-28 15:50:00]

  • 已修改games/base.py
  • 更改在get_help_message()的成语接龙部分添加黑名单相关指令说明
    • 添加 .idiom reject [词语] - 拒绝词语加入黑名单(仅发起人)
    • 添加 .idiom blacklist - 查看黑名单
  • 原因:用户反馈.help帮助信息中看不到黑名单机制的使用说明
  • 阻碍因素:无
  • 状态:未确认

[2025-10-28 15:55:00]

  • 已修改games/idiom.py
  • 已创建data/idiom_blacklist.json
  • 更改:将黑名单机制从游戏状态改为全局永久存储
    1. 创建data/idiom_blacklist.json作为全局黑名单数据文件
    2. 在IdiomGame.init()中添加黑名单文件路径和懒加载变量
    3. 添加_load_blacklist()方法从文件懒加载全局黑名单
    4. 添加_save_blacklist()方法保存黑名单到文件
    5. 修改_validate_idiom()方法检查全局黑名单而非游戏状态中的黑名单
    6. 修改_start_game()方法移除state_data中的blacklist字段初始化
    7. 修改_reject_idiom()方法将词语添加到全局黑名单并保存到文件
    8. 修改_show_blacklist()方法显示全局黑名单,不再依赖游戏状态
    9. 更新所有提示信息,明确说明是"永久禁用"
  • 原因:用户要求被拒绝的词语应该永久不可用,而不是仅本局游戏不可用
  • 阻碍因素:无
  • 状态:未确认

最终审查

待REVIEW模式完成后填写