# 关卡、旋转、碰撞与难度 ## 数据格式 平顶六边形使用轴向 `(q,r)`,逻辑 y 轴向下。中心为 `x=1.5qR`、`y=√3(r+q/2)R`。 | 方向 | 朝向 | 邻格变化 | | --- | --- | --- | | 0 | ↑ | (0,-1) | | 1 | ↗ | (1,-1) | | 2 | ↘ | (1,0) | | 3 | ↓ | (0,1) | | 4 | ↙ | (-1,1) | | 5 | ↖ | (-1,0) | ```json { "version": 1, "id": "my-level", "name": "转个方向", "rotationEnabled": true, "moveLimit": 3, "cells": [{ "q": 0, "r": 0, "tracks": [3, 4, 5, 0, 1, 2] }], "tiles": [{ "id": "t0", "q": 0, "r": 0, "dir": 1, "color": 0 }] } ``` `tracks[i]` 为进入 i 端口后使用的出口,必须满足 `tracks[tracks[i]]===i` 且不能与自己相连。六端口共有 15 种完整配对。`color` 为 0–3。`rotationEnabled` 可选,默认开启;旧版 JSON 仍可导入,但会按新的碰撞规则重新验证。 导入限制:1–61 格、坐标半径不超过 4、步数 1–999。编辑器提供半径 2/3 的常用板型。底板不具备六重旋转对称性时,禁用整体旋转,避免棋子旋转后悬空。 ## 旋转是真实的规则变化 顺时针一步将所有底板格子变为 `(q,r) → (-r,q+r)`,同时将轨道端口和对应出口都加 1(模 6)。上层棋子的 `(q,r,dir)` 均不改变。六次旋转恢复原状。 v2 旋转不扣步,点击棋子(含碰撞)扣 1 步。撤销保存并恢复底板、棋子、步数、朝向和旋转计数。重开读取原始关卡,不能从已旋转的中间状态重开。 ## 连续碰撞 `path-math.js` 同时服务渲染与碰撞:每条三次贝塞尔轨道采样为 20 段,碰撞针对这些实际绘制的折线进行连续扫掠,而不是仅检查当前动画帧的位置。 每个棋子的顶面碰撞体为半径 `0.88R` 的平顶六边形,阴影和视觉侧壁不计入碰撞。两个同向六边形的 Minkowski 和是半径 `1.76R` 的六边形。将移动中心线的每段与此凸六边形做半平面裁剪,即可得到最早接触时刻。长段移动也不会穿透。 例如:移动棋子在 `(1,1)` 向上走,另一棋子在 `(0,0)`。路线经过的格子不含 `(0,0)`,但经过相邻两格之间时,移动棋子的侧面可能擦到它,因此仍被阻挡。这比仅检查路线格子占用更严格。 判定发生在移动前,动画只展示结果:成功沿线离场;失败走到接触位置再退回。动画期间允许连续点击不同棋子进入队列,执行前按最新棋盘重新判断路线;碰撞会清空等待队列。棋子仍依次运动,避免时序歧义。生成器、求解器、提示与工坊都调用同一个 `trace()`。 ## 旋转求解与生成 移走可行棋子只会减少障碍,不改变轨道,因此在任意朝向下先移除所有安全棋子不会损害后续可解性。求解器对“朝向+剩余棋子集合”做 BFS,每次转盘代价为 1,到达一个朝向后先消除所有可离场棋子。 v2 最短扣费步数 = 初始棋子数;最少操作次数 = 初始棋子数 + 最少旋转数。BFS 返回混合 `tap` / `rotate` 动作序列。最大扩展状态数为 20,000;若触及上限,则返回 `exhausted` 表示尚未确定,不能宣称无解。 关卡生成先在碰撞规则下逆向放入可离场棋子,再旋转初始底盘,筛选必须旋转才能完成的布局,最后重新求解验证。主线按评分非递减排列,共 24 关,必要旋转 1–3 次。 ## 数字化难度(0–100) 设 N=棋子数、T=忽略占用的平均转弯数、W=解答中的消除层数、F=初始无碰撞可离场数量、R=最少旋转数、K=N=最短扣费步数、M=上限: ```text 规模 = min(1, N/37) × 15 弯道追踪 = min(1, T/5) × 20 解锁层数 = min(1, max(0,W-1)/9) × 20 路线阻塞 = (1-F/N) × 15 必要旋转 = min(1, R/4) × 20 步数压力 = clamp(1-(M-K)/max(1,0.4N), 0, 1) × 10 总分 = 四舍五入各项未取整值之和 ``` 空关卡为 0 分且不能判为有效可解关卡。不可解、搜索未确定和步数不足分别展示。分项单独取整,显示值之和可能与总分略有差异。 0–29 轻松、30–49 进阶、50–69 烧脑、70–100 挑战。目前 24 关范围为 25–75。它是用于关卡排序的结构估计,没有经过玩家通关率标定;后续可用首次成功率、碰撞率、提示率、旋转次数、撤销率与耗时校准。