Files
NumberSwipe_New/modes/03-hex-walls/README.md
T
cabinw 8026e4628d 初始提交:三玩法 Web 原型与设计文档
- 玩法一 数字一笔:规则库、求解器、26 关、竖屏触摸 Web 原型、测试
- 玩法二 连连气球:连消畅玩版核心、Web 原型、Cocos 球槽组件与导出脚本
- 玩法三 六边一笔:规则库、求解器、10 关 + 转墙实验包、Web 原型、测试
- 产品文档、UI 设计规范、各玩法 GDD / HANDOFF
- 文档移除全部外部参考作引用;删除玩法二 v0 旧稿
2026-09-16 14:30:59 +08:00

114 lines
6.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 玩法三 · 六边一笔
六边形上一笔画走遍;墙贴在边上,挡住那一条邻接;线索数字必须踩在对应步号。
本目录自包含:规格、关卡、规则代码、求解器、生成器和 Web 原型。不 import 玩法一的矩形模型,也不把墙做成玩法一的后期关。壳的约定见 [`docs/PRODUCT.md`](../../docs/PRODUCT.md)。
几何锁六边形,墙是边不是格。关卡、资源、文案全部原创,不使用第三方题库或素材。
## 状态
M1/M2 已达:竖屏触摸 Web 原型可玩,10 关全部经求解器断言「唯一解 + 墙参与唯一性 + 无冗余墙」,存档、提示、音效、振动齐全。另有 **转墙** 实验包 9 关(GDD 附录 A)。下一步 M4 迁 Cocos。
## 目录
| 路径 | 用途 |
|---|---|
| [`docs/GDD.md`](docs/GDD.md) | 本玩法规格(权威) |
| [`docs/HANDOFF.md`](docs/HANDOFF.md) | 交接文档:实现了什么、怎么实现、与 GDD 的偏差、待办与 Cocos 迁移顺序 |
| [`levels/pack-1-tutorial.json`](levels/pack-1-tutorial.json) | 第一包 10 关 |
| [`levels/pack-2-spinner.json`](levels/pack-2-spinner.json) | 第二包(实验):转墙 9 关 |
| [`src/`](src/) | **纯 TS 规则层,零 DOM / 零 Cocos 依赖**。Web 与 Cocos 共用 |
| [`web/`](web/) | 浏览器原型:DOM / Canvas / PointerEvent / localStorage 粘合层 |
| [`tools/`](tools/) | 求解器命令行:全关卡校验、关卡设计辅助、随机生成器 |
| [`tests/`](tests/) | 规则层单元测试(node:test) |
`src/` 分层:
```
types.ts 关卡 JSON 结构(轴坐标 + 墙边)
board.ts HexBoard:轴坐标六邻接、墙、转墙(按步号判定)、几何邻接 / 可走邻接、连通性
game.ts 对局状态机:Command → GameEvent(start/append/undo/release/resume/reset;含 wallHit)
input.ts 手势语义:按下/移动/松手 + “当前压在哪个格” → Command
solver.ts 枚举满足线索的哈密顿路径、唯一解、墙有效性、提示(下一步 / 退回分叉)
geom.ts 纯几何:圆角多边形、凸裁剪、斜纹带
layout.ts 六边形布局:轴坐标 ↔ 像素、命中测试(带死区)、共用边、桥、墙带
view.ts HexBoardView:格/桥/数字/墙/冲突/提示/过关动效,只调用 Painter
painter.ts 绘制原语接口(多边形、线、圆、居中文字)
theme.ts 配色
progress.ts 存档(KeyValueStore 抽象,桶 mode:03-hex-walls)
levels.ts 关卡包解析
```
## 运行
```bash
cd modes/03-hex-walls
npm install
npm run dev # 起本地服务(默认 8100)+ 监听改动,终端会打印手机可访问的局域网地址
npm run build # 打包到 web/dist/app.js,之后可直接双击 web/index.html
npm run check # 类型检查(含 src/ 无 DOM 校验)+ 单元测试 + 全关卡校验
```
`?dev=1` 解锁全部关卡并暴露 `window.__hexWalls` 调试句柄(自动化手势测试用)。
关卡工具:
```bash
npm run validate # 每关:连通、恰好 1 解、第 3 关起去墙后不唯一、无冗余墙、转墙不可换静态墙
npm run validate -- 1-7 # 只看某关,并打印解
npm run design -- 1-7 --minimize # 当前线索里哪些可删
npm run design -- 1-7 --walls # 哪些墙可删
npm run design -- 1-7 --suggest 3 --path a,b,c,... # 给作者解找最少线索
npm run generate -- --shape hex2 --holes 2 --walls 3 --clues 3 --seed 7 --count 5 # 出候选盘
npm run generate -- --shape rect4x2 --walls 0 --spinners 1 --clues 2 --seed 212 # 带转墙的候选
```
## 第一包 · 10 关
每关只加一个旋钮(GDD §7)。「去墙解」= 拿掉全部墙后满足线索的解数,> 1 才说明墙在干活。
| 关 | N | 教什么 | 墙 | 线索 | 去墙解 |
|---|---|---|---|---|---|
| 1-1 | 3 | 滑动,邻格自动出步号 | 0 | 1 | – |
| 1-2 | 5 | 必须走完所有格 | 0 | 1, 5 | – |
| 1-3 | 4 | 第一堵墙:看起来相邻,滑不过去 | 1 | 1, 4 | 2 |
| 1-4 | 7 | 墙贴在 1 旁边,第一步只剩一个方向 | 1 | 1, 7 | 2 |
| 1-5 | 8 | 中段线索:3 在 1 旁边却要绕一步 | 1 | 1, 3, 8 | 2 |
| 1-6 | 11 | 空洞 + 两堵墙 | 2 | 1, 9 | 7 |
| 1-7 | 12 | 先想再画:旁边那格是陷阱 | 2 | 1, 9 | 8 |
| 1-8 | 12 | 综合:3 墙 3 线索 | 3 | 1, 6, 12 | 13 |
| 1-9 | 15 | 走廊:墙把一侧切成单向通道 | 3 | 1, 11, 15 | 16 |
| 1-10 | 19 | 小考:满花盘 4 墙 | 4 | 1, 10, 14 | 26 |
## 第二包 · 转墙(实验)
绕顶点转的墙,每走一格顺时针转 120°,轴心那端有圆点。规则与铁律见 GDD 附录 A。
| 关 | N | 教什么 | 静态墙 | 转墙 | 线索 | 去墙解 |
|---|---|---|---|---|---|---|
| 2-1 | 7 | 起手后墙正好挡住直觉的第一步,绕回来时它已转开 | 0 | 1 | 1, 7 | 2 |
| 2-2 | 8 | 用线索 4 算拍子:绕两格到 4,再往左时墙刚好开 | 0 | 1 | 1, 4 | 6 |
| 2-3 | 12 | 静态墙 + 转墙综合 | 1 | 1 | 1, 12 | 9 |
| 2-4 | 7 | 两个转墙,轴心相邻 | 0 | 2 | 1, 2 | 8 |
| 2-5 | 10 | 三角盘,两个转墙分居两端 | 0 | 2 | 1, 6 | 8 |
| 2-6 | 12 | 三个转墙围着中心格 | 0 | 3 | 1, 11 | 20 |
| 2-7 | 15 | 三个转墙挤在右侧 + 一堵静态墙 | 1 | 3 | 1, 7 | 49 |
| 2-8 | 17 | 三个转墙分布三处 | 0 | 3 | 1, 10 | 52 |
| 2-9 | 19 | 满花盘,四个转墙 | 0 | 4 | 1, 8, 17 | 41 |
## 交互(已实现)
- 有线索 `1` 只能从它起手,点别处 `1` 抖一下。
- 按住滑到相邻、无墙、未走格 → 追加(弹一下、桥长出来、步号淡入、音高随步号上升)。
- 滑向有墙的邻格 → 墙闪白 + 红描边 + 轻推、短振动、闷响;不追加,指针逻辑上仍在末端。撞转墙同样反馈。
- 每追加 / 撤销一格,转墙做 120° 旋转动画。
- 滑回上一格 → 撤销。不相邻 / 已走且非上一格 → 忽略。
- 松手保留;从末端继续;点前一格撤销;点末端旁的空格直接追加。
- 线索踩错 → 红底 + 角标写应有步号,不中断手势。走完且全对 → 提亮、扫光、自动下一关。
- 提示:起点 / 下一步 / 退回分叉(压暗要退的段)/ 起手错(重开按钮脉冲)。
## 移植到 Cocos Creator
见 [`docs/HANDOFF.md`](docs/HANDOFF.md) §4.2 D。要点:`src/` 整目录拷进 `assets/modes/03-hex-walls/scripts/` 不改一行;写 `GraphicsPainter`(`Graphics.moveTo/lineTo/close/fill/stroke` + `Label` 池);触摸事件转节点坐标后喂 `hitTest` → `PointerInput`;`sys.localStorage` 实现 `KeyValueStore`。