Back to home@jinzheng8115

dsh-Minesweeper

DeepSeek Harness minesweeper plugin — agent tool set + human panel sharing one board. 扫雷插件:agent 工具集与人类面板共享同一棋盘。

Stars
0
Language
TypeScript
Created
Aug 24, 2026
Updated
Aug 24, 2026
GitHub repo

Introduction

dsh-minesweeper

DeepSeek Harness 扫雷插件 —— agent 与人类同棋盘对战

两种玩法(同一张棋盘)

  • Agent:模型通过 minesweeper_* 工具经真实工具流水线落子
  • 人类:Web UI 侧边栏点「⛏ 扫雷」打开浮层面板(非模态,点聊天不会关闭);左键挖开 / 右键插旗 / 双击数字格快翻;切换难度立即开新局。面板每 2.5s 轮询,AI 落子的格子闪烁高亮,状态栏显示每步归属(你 / AI)
  • 任一方触发终局,广播一次 minesweeper/game-over 事件(排行榜等插件可监听)

防作弊:引擎棋盘每个格子都带 isMine 字段,工具渲染与 HTTP API 共用同一个防作弊滤网(visibleGlyph),双方都只能看到玩家视角信息。

工具集

工具说明
minesweeper_new开新局。可指定难度 / 自定义尺寸(rows+cols+mines)/ 随机种子
minesweeper_state查看当前盘面(不含未翻开格子的地雷信息)
minesweeper_auto服务端确定性求解:迭代执行「旗数满足→快翻」「剩余隐藏格恰为雷数→插旗」,绝不猜测。把机械步骤从 LLM 挪到服务端
minesweeper_moves批量按顺序执行多步(reveal/flag/chord,≤40 步,遇终局停止),减少逐格往返
minesweeper_reveal挖开格子;踩雷即输,翻开全部安全格即胜
minesweeper_flag插旗 / 拔旗(toggle | place | remove)
minesweeper_chord快翻:数字格周围旗数恰等于数字时批量翻开

另注册系统提示词策略段(minesweeper-strategy):引导模型「先 auto 清机械步骤 → 确定的多步用 moves 批量提交 → 只在真正需要推理时逐步来」。

配置

- id: minesweeper
  name: dsh-minesweeper
  config:
    defaultDifficulty: beginner   # beginner | intermediate | expert

安装与运行

npm run build                                          # esbuild 打包 src → lib/index.js
dsh plugin --profile web add /Volumes/Code/Coding/DSH/dsh-Minesweeer   # 安装进 profile
nohup dsh --profile web --no-open > /tmp/dsh-web.log & # 启动 Web UI (http://127.0.0.1:3080)

安装后无需 --patch:bundle 自带的 cordis.patch.yml 会把插件插入配置树;dsh.client 声明让宿主自动 serve /plugins/dsh-minesweeper/client.js 并注入浏览器启动图。

本地开发也可用 overlay 免打包加载工具半边(见 examples/dev.overlay.yml),但客户端面板需要 bundle 安装才能被发现。

架构

src/
├── game/          纯游戏内核(移植自 Retro Minesweeper,零框架依赖)
│   ├── types.ts       Board/Cell/GameState 类型
│   ├── config.ts      三档难度 + 邻格/安全区计算
│   ├── board.ts       建盘、布雷(RNG 可注入 + mulberry32 种子随机)
│   └── gameLogic.ts   reveal/chord/flag/胜负判定(纯函数)
├── session.ts     单局会话(无 React 版 useMinesweeper;计时惰性计算,无定时器)
├── service.ts     MinesweeperService —— 人机共享的唯一状态源 + 终局事件恰好广播一次
├── routes.ts      人类面板 HTTP API(GET state / POST new·reveal·flag·chord,同源防护)
├── render.ts      模型可见渲染(防作弊层,visibleGlyph 是字形规则的唯一实现点)
├── index.ts       Cordis 接线:工具注册 + 路由挂载 + 配置 schema + 事件
└── ../client/client.js  人类玩家面板(plain JS + React,宿主 __ModuleLoader__ 加载,slots 注册侧边栏入口)(唯一依赖 harness 的文件)

关键实现细节:

  • 依赖声明双保险:模块级 export const inject = ['tools'] 供 loader 读取;同时 Object.assign(apply, { inject, Config }) 附着到函数上,使直接 ctx.plugin(apply) 挂载(测试 / 组合场景)也能被 cordis 正确解析依赖并用 Standard Schema 校验配置。
  • 种子可复现:相同 seed + 相同操作序列 ⇒ 同一局,便于评测与调试。

测试

npm run typecheck    # TS 全量类型检查(含真实 @deepseek-ai 类型)
npm run smoke        # 无头冒烟:逻辑不变量 + 防作弊不泄露 + 种子可复现
npm run integration  # 真实 Cordis 运行时:挂载 SystemPrompt → tools → 本插件,
                     # 经 ctx.tools.execute 完整管线对局并验证事件广播
npm test             # 两者全跑