From e27015c4d24976c34db0098f21faabbc54ba612d Mon Sep 17 00:00:00 2001 From: unanmed <1319491857@qq.com> Date: Wed, 9 Sep 2026 19:30:12 +0800 Subject: [PATCH] =?UTF-8?q?fix(02-02):=20cost=20=E5=AE=88=E5=8D=AB?= =?UTF-8?q?=E5=85=81=E8=AE=B8=20Infinity=EF=BC=8C=E4=BB=85=E6=8B=A6=20NaN?= =?UTF-8?q?=20=E4=B8=8E=E8=B4=9F=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages-user/data-system/src/path/finder.ts | 5 +++-- .../data-system/src/path/system.test.ts | 21 +++++++++++++++++++ packages/common/src/logger.json | 2 +- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/packages-user/data-system/src/path/finder.ts b/packages-user/data-system/src/path/finder.ts index 7a1963b..919369b 100644 --- a/packages-user/data-system/src/path/finder.ts +++ b/packages-user/data-system/src/path/finder.ts @@ -136,13 +136,14 @@ export class PathfindingFinder implements IPathfinder { } /** - * 获取进入指定位置节点的损失,损失值不是有限数字或为负数时告警并按损失 1 处理 + * 获取进入指定位置节点的损失,损失值为 NaN 或负数时告警并按损失 1 处理, + * Infinity 为合法损失值 * @param block 位置信息 */ private getNodeCost(block: ILayerLocation): number { if (!this.cost) return 1; const value = this.cost(block); - if (!Number.isFinite(value) || value < 0) { + if (Number.isNaN(value) || value < 0) { logger.warn(174); return 1; } diff --git a/packages-user/data-system/src/path/system.test.ts b/packages-user/data-system/src/path/system.test.ts index 93c83e1..a4cc80e 100644 --- a/packages-user/data-system/src/path/system.test.ts +++ b/packages-user/data-system/src/path/system.test.ts @@ -410,6 +410,27 @@ describe('pathfinding system', () => { expect(result.ret).toHaveLength(2); }); + // 验证 Infinity 是合法损失值:不告警且路径绕开高损失格 + it('allows Infinity as a legitimate cost without warning', () => { + const fixture = createSystem([1, 1, 1, 1, 1, 1, 1, 1, 1], 3); + injectPredicate(fixture); + const cost: PathCostFunction = block => + block.locator.x === 1 && block.locator.y === 1 + ? Number.POSITIVE_INFINITY + : 1; + fixture.system.finder.useCostFunction(cost); + + const result = modules.logger.catch(() => + fixture.system.finder.find({ x: 0, y: 1 }, { x: 2, y: 1 }) + ); + + expect(result.info.map(info => info.code)).not.toContain(174); + expect(result.ret).toHaveLength(4); + for (const step of result.ret) { + expect(step.to).not.toEqual({ x: 1, y: 1 }); + } + }); + // 验证不可达目标返回空数组且不移动对象 it('returns an empty path and never moves for unreachable targets', () => { const fixture = createSystem([1, 6, 1, 1, 6, 1, 1, 6, 1], 3); diff --git a/packages/common/src/logger.json b/packages/common/src/logger.json index 56f051d..e6a6536 100644 --- a/packages/common/src/logger.json +++ b/packages/common/src/logger.json @@ -239,6 +239,6 @@ "171": "Event id '$1' not found in event store, event will be skipped.", "172": "Event returned non-boolean value '$1' during reduction. JavaScript short-circuit semantics will be used.", "173": "Pathfinding input is invalid or a required binding (map state, map layer) is missing. An empty result will be returned.", - "174": "Pathfinding cost function returned a negative value. Default cost 1 will be used instead." + "174": "Pathfinding cost function returned a negative or NaN value. Default cost 1 will be used instead." } }