fix: 高度偏好默认关闭 —— 它让寻路器完全规划不出路径(自动扩地的直接拦路虎)
实测定位:高度偏好的启发值实现与 mineflayer-pathfinder 的内部约定冲突。 该库每次 compute() 返回 partial 时,用 h 最小的节点当 partial 路径的终点 (astar.js: if (neighborNode.h < this.bestNode.h) this.bestNode = neighborNode), 而 AltitudeGoal 把 h 减去了 权重 × y,于是「又高又偏」的节点 h 反而更小, partial 路径被引向高处而不是目标附近 —— A* 一直在算、永不收敛, 机器人一次移动指令都发不出来。 王城平台上的对照实测(其余配置完全相同): - altitudePreference = true → inputTicks = 0,任务永远停在「寻路超时,重新寻路」 - altitudePreference = false → inputTicks = 237,立刻开始移动 顺带排除:searchRadius 从 -1 改到 128 对结果没有任何影响, 所以不是「搜索空间无界」导致的;pathfinder 与 manual 两种执行器表现一致。 改动: - expansionConfig 默认 altitudePreference 改为 false,并在注释里写清原因与 「想重新启用应该怎么做」(把偏置改成低处加移动代价,保持启发值只反映真实距离); - AltitudeGoal 的类注释补上完整推导与实测数据,避免以后有人又把它打开; - 新增回归用例:断言默认关闭,并用启发值差值把「为什么必然出问题」固化下来。 测试 468 → 469,全绿。
这个提交包含在:
@@ -35,6 +35,21 @@ test('AltitudeGoal 使用 GoalNearXZ 时保留其到达范围', () => {
|
||||
assert.strictEqual(goal.isEnd({ x: 100, y: 70, z: 201 }), true, '范围内算到达');
|
||||
});
|
||||
|
||||
test('高度偏好默认关闭:它的启发值会破坏 partial 路径的终点选择', () => {
|
||||
// 回归:开启时实测 inputTicks = 0(寻路器一次移动指令都发不出),
|
||||
// 关掉后 inputTicks = 237(立刻开始移动)。详见 AltitudeGoal 的注释。
|
||||
const config = defaultConfig();
|
||||
assert.strictEqual(config.altitudePreference, false, '默认必须是关闭的');
|
||||
// 上面的差值断言同时说明了「为什么」:h 被减去了 weight × y,
|
||||
// 而 mineflayer-pathfinder 用 h 最小来挑 partial 路径终点,
|
||||
// 于是又高又偏的节点会胜出,路径永远到不了目标附近。
|
||||
const goal = new AltitudeGoal(new GoalXZ(0, 0), 0.1, 64);
|
||||
const farButHigh = goal.heuristic({ x: 0, y: 300, z: 0 }); // 就在目标正上方
|
||||
const nearButLow = goal.heuristic({ x: 40, y: 64, z: 0 }); // 离目标 40 格
|
||||
assert.ok(farButHigh <= nearButLow,
|
||||
`高处节点的启发值 ${farButHigh} 不大于低处近节点的 ${nearButLow},正是问题所在`);
|
||||
});
|
||||
|
||||
// ==================== 长距离分段寻路 ====================
|
||||
//
|
||||
// mineflayer-pathfinder 只能规划已加载区块范围(实测线上约 8 区块 ≈ 130 格),
|
||||
|
||||
在新工单中引用
屏蔽一个用户