Files
HexTrails/labs/d5/README.md
T
cabinwandClaude Opus 5 643cba0ed9 feat(levels): D5 three-rotation prototype
The shipped 1000 levels have a hole: 568 of them need no rotation at all, and
none needs more than two — the mechanic the game is built on is mostly
decoration. This fills the empty band with levels that need at least three.

createDeepLock builds a four-piece chain where each link only releases at a
later orientation, and growDeepLevel packs the rest of the board around it
without opening a shortcut. Candidate pools are built per orientation and left
untruncated; ranking by bend count first starved the packer and capped levels
at four to six pieces instead of twelve.

deadTurnAudit enumerates every reachable (orientation, remaining-set) state to
prove no dead ends exist, and counts how long a player can be left with
nothing to do — solvable and feeling solvable are different things, which is
what "level 2 is impossible" turned out to be about.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 14:00:33 +08:00

41 lines
3.4 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.
# D5 · 三转链式锁构造原型
目的:验证在现行规则(消除单调、旋转免费可逆)下,能否稳定构造出**最少需要三次旋转**、且**开局大部分棋子被锁住**的关卡。这是 v0.6 难度曲线里 D5 档的内容来源;v0.5 千关里该档为 0,`createStageSeed` 只能产出两转锁。
打开:`npm run dev` 后访问 `/labs/d5/index.html`。只读 `levels/prototypes/d5.json`,不写入主线存档。
## 构造方法
`src/deep-lock.js`
1. **`createDeepLock(base)`** — 四子链式锁 A/B/C/D。朝向 0 全部被锁;+1 只有 B 能走;+2(B 走后)只有 C 能走,A 与 D 互锁;转回 +1 放 A,再放 D。网格路线只用来提议,每一阶段都用主游戏的扫掠碰撞 `trace()` 逐条认证,最后由 `solveRotations()` 证明不存在一转或两转的清盘方案。
2. **`growDeepLevel(base, lock, { target, layerShares })`** — 反向插入更多棋子,按朝向 0 / 1 / 2 分层配额;优先选「在更早的朝向都被挡」的棋子,使它们真正等旋转;每插一枚重新求解,最少旋转数跌破 3 即拒绝。
3. **`deepLevelStats(level)`** — 锁住占比(首转时剩余)、每次旋转释放数、首转是否只有一侧能开路、波次。
## 一次扫描的产出(6 形态 × r3/r4 × 8 种子)
```
找到锁 55/96 · 长成 R≥3 关 55 · 旋转次数 {3:47, 4:1, 5:7}
锁住占比中位 78%(v0.5 现状 22%)· 每转释放 ≥2 枚 38/55 · 首转单向 9/55
随机玩家 动作÷棋子 中位 7.5(v0.5 全库 1.67,v0.4 手作 3.42)
switchback r3、crossing r3 产出 0:小盘上这两种形态找不到满足四子约束的候选
```
重新生成:`node scripts/prototype-d5.mjs --seeds=8 --keep=18`(`--radii=3,4,5` 可含 91 格;默认不含)。
## 「无解」问题与可玩性门槛
第一批里的第 02 关(orbits r3 s3)被试玩者判为无解。穷举全部 324 个可达状态:0 个死局,参考解在真实界面里也能清盘。问题出在体感:**开局 100% 锁死 + 首转只有右边有效 + 最后一步要转回来**。先往左转的人连看 3 个空朝向,右右之后继续右转的人连看 4 个——两条路都读作"无解"。
对策分两层,都已落地:
1. **结构门槛**(`scripts/prototype-d5.mjs`):`deadTurnAudit()` 穷举玩家可达的全部状态(任意点击顺序、任意旋转序列),证明没有死局,并统计「双向死转态」(卡住时左右各转一次都打不开的状态数)与「最长盲转」。入选关必须:首转两侧都能开路、开局锁住 ≤90%、无不可解可达态;按双向死转态升序排。现在前 4 关这两项都是 0,随机玩家动作÷棋子回到 3.6–6.5。
2. **反馈**(`labs/d5/app.js`):卡住后闲置 3 秒,正确的旋转按钮开始脉冲并提示方向——即 §07 第 1 条的做法,方向永远不即时给出。任何输入都会清掉提示。
## 尚未解决
- 随机玩家的动作数仍高于手作版(v0.4 为 3.42);D5 放在第 501 关后是否合适,要真人试玩。
- 现在的参考解是求解器给出的最短解,不是作者解;正式接入生产时应保留作者见证(同 `createStageSeed`)。
- 「首转释放 ≥2 枚」只在扫描时排序,未在生长时强制。
- 「双向死转态 = 0」目前只是排序偏好,不是硬门槛;D5 后段若需要单向关,应配合闲置提示一起上线,不能单独放。