You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js迷宫校验时条件不满足仍向数组重复push元素致死循环问题

Node.js迷宫可达性校验死循环问题修复

问题背景

我正在使用Node.js开发一款终端迷宫游戏,随机生成的迷宫包含以下元素:

const hat = '^';
const hole = 'O';
const fieldCharacter = '░';
const pathCharacter = '*';

玩家需要从起点出发穿越迷宫找到帽子,迷宫全量数据存储在randomArr变量中。由于迷宫为随机生成,可能出现帽子被洞穴完全包围、玩家无法抵达的无解情况,因此需要实现前置可达性校验逻辑,判断当前生成的迷宫是否存在通关路径。

现有代码运行时会陷入无限循环:逻辑设计层面,仅当相邻格子为可通行的场地字符、且该格子未被访问过时,才会将对应坐标推入visited访问记录数组,但实际运行时相同坐标会被反复推入数组,最终触发死循环。
现有循环逻辑的起始部分代码如下:

while (true) {           
    //checking if next move is a winning move
    if (randomArr?.[p[0]]?.[p[1] + 1] === hat || randomArr?.[p[0]]?.[p[1] - 1] === hat || randomArr?.[p[0] + 1]?.[p[1]] === hat || randomArr?.[p[0] - 1]?.[p[1]] === hat) {
        console.table(visited, visitedTwice, visited3x, visited4x, visited5x);
        console.log(`solution found, reached postion ${p}`)
        return randomArr;
    }          
    //checking if neighbouring square hasn't been visited, if no, go there
    else if (randomArr?.[p[0]]?.[p[1] + 1] === fieldCharacter && !visited.includes([ p[0], p[1] + 1 ])) {
        p = [p[0], p[1] + 1];
        visited.push([p[0], p[1]]);
        //console.log(visited.includes([ p[0], p[1] + 1 ]), 0);
        //console.log(visited);
    } else if (randomArr?.[p[0]]?.[p[1] - 1] === fieldCharacter && !visited.includes([ p[0], p[1] - 1 ])) {
        p = [p[0], p[1] - 1];
        visited.push([p[0], p[1]]);
        //console.log(visited.includes([ p[0], p[1] - 1 ]), 1);
        //console.log(visited);
    } else if (randomArr?.[p[0] + 1]?.[p[1]] === fieldCharacter && !visited.includes([ p[0] + 1, p[1] ])) {
        p = [p[0] + 1, p[1]];
        visited.push([p[0], p[1]]);
        //console.log(!visited.includes([ p[0] + 1, p[1] ]), 2);
        //console.log(visited);
    } else if (randomArr?.[p[0] - 1]?.[p[1]] === fieldCharacter && !visited.includes([ p[0] - 1, p[1] ])) {
        p = [p[0] - 1, p[1]];
        visited.push([p[0], p[1]]);
        //console.log(!visited.includes([ p[0] - 1, p[1] ]), 3);
        //console.log(visited);

运行时代码会反复触发前两个else if分支,持续向visited数组中添加重复坐标。


问题根因

死循环由两个核心bug直接导致:

  • 访问判断逻辑完全失效:JavaScript中Array.prototype.includes判断数组这类引用类型时,比对的是内存地址,而非数组内存储的值。你每次写!visited.includes([p[0], p[1]+1])时,都新建了一个独立的数组对象,哪怕坐标值和visited里已存的完全一致,判断结果永远是false,相当于“未被访问过”的校验根本没生效。
  • 遍历逻辑没有回溯能力:现有写法是单路径向前探索,遇到岔路只会按固定优先级选第一个可走的方向,走到死路后没有回退到上一个岔路口选择其他方向的机制,只会在相邻两个可通行格子之间来回移动。

修复方案

1. 替换访问记录存储结构

放弃用嵌套数组存坐标,将坐标序列化为x,y格式的字符串存入Set,判断是否访问过时直接比对字符串值,从根源解决引用类型判断失效的问题:

// 初始化访问集合,提前存入起点坐标
const visited = new Set();
const startX = 0, startY = 0; // 替换为实际的玩家起点坐标
visited.add(`${startX},${startY}`);

2. 改用标准BFS实现可达性检测

迷宫可达性是经典的图搜索问题,不要用裸while(true)硬写遍历逻辑,直接用广度优先搜索(BFS)实现,逻辑简单且不会出现死循环:

function checkMazeValid(randomArr, hat, fieldCharacter, hole, startPos = [0, 0]) {
    const rowCount = randomArr.length;
    const colCount = randomArr[0].length;
    const visited = new Set();
    // 队列存储待遍历的坐标
    const searchQueue = [startPos];
    visited.add(`${startPos[0]},${startPos[1]}`);
    // 四个探索方向:上、下、左、右
    const directions = [[-1, 0], [1, 0], [0, -1], [0, 1]];

    while (searchQueue.length > 0) {
        const [currentX, currentY] = searchQueue.shift();
        // 遍历四个相邻格子
        for (const [dx, dy] of directions) {
            const nextX = currentX + dx;
            const nextY = currentY + dy;
            // 越界直接跳过
            if (nextX < 0 || nextX >= rowCount || nextY < 0 || nextY >= colCount) continue;
            const posKey = `${nextX},${nextY}`;
            // 已访问过直接跳过
            if (visited.has(posKey)) continue;
            const cellValue = randomArr[nextX][nextY];
            // 找到帽子,说明迷宫有解
            if (cellValue === hat) return true;
            // 是可通行的空地,加入队列待遍历
            if (cellValue === fieldCharacter) {
                visited.add(posKey);
                searchQueue.push([nextX, nextY]);
            }
        }
    }
    // 所有可通行区域遍历完都没找到帽子,迷宫无解
    return false;
}

如果要在原有代码逻辑上修改,除了替换Set做访问记录外,还需要补全回溯逻辑:走到死胡同(四个方向都无法通行)时,要回退到上一个坐标,不能停在原地反复判断相邻格子,否则必然出现来回横跳的问题。


内容的提问来源于stack exchange,提问作者chylinski

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 05:09:16