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

基于单元格值融合的迷宫生成代码死循环问题求助

排查迷宫生成代码的死循环与生成失败问题

嗨,我仔细扒了你的代码,发现几个致命的小问题,直接导致了死循环、生成失败甚至调试断点失效,咱们一个个说:

1. 内存分配错误(断点失效的元凶)

你定义的Maze结构体里,array是二级指针MazeCell**,但在initMaze里却用了malloc(nbCells*sizeof(MazeCell))——这是给一级指针分配内存的写法!这种不匹配的内存分配会直接破坏堆结构,导致程序运行时内存越界,IDE的调试器根本没法正常工作,断点自然触发不了。

如果你的逻辑是把迷宫当成一维数组处理(看代码里是用i从0到m*n-1遍历),那直接把结构体里的array改成一级指针就行:

typedef struct _maze_t {
    int row, column;
    MazeCell* array; // 改成一级指针,匹配一维数组的用法
} Maze;

这样原来的内存分配代码就没问题了。

2. 随机数函数逻辑错误(永远选不到左侧墙)

你的rand_a_b函数返回的是[a, b)区间的随机数,但你调用rand_a_b(1,2)想选1或2——这根本不可能!因为b-a=1,rand()%1永远是0,加a=1后结果永远是1,左侧墙的代码块从来不会执行!

这就导致迷宫只能合并上下区域,左右区域永远孤立,循环永远等不到所有单元格值相同的时刻,直接死循环。

修复方法有两种:

  • 要么修改函数返回[a, b]区间:
    int rand_a_b(int a, int b){
        return rand() % (b - a + 1) + a; // 这样rand_a_b(1,2)会返回1或2
    }
    
  • 要么调用时传入rand_a_b(1,3),利用原来的[a,b)区间覆盖1和2。

3. 墙的判断条件错误(漏掉有效合并,触发无效合并)

  • 处理上方墙时,你写的if(nbAl>n),比如n=5时,索引5的单元格(第二行第一个)的nbAl>n是5>5?不成立,直接跳过了它和上方单元格(索引0)的合并,漏掉了大量有效合并机会。正确的判断应该是if(nbAl >=n)(只要不是第一行的单元格,都有上方墙)。
  • 处理左侧墙时,if(nbAl>0)不够,比如索引5(第二行第一个)的nbAl-1是4(第一行最后一个),这会错误地合并不同行的单元格,导致区域逻辑混乱。正确的判断应该是if(nbAl %n !=0)(只有不是每行第一个的单元格,才有左侧墙)。

4. 循环终止条件的逻辑漏洞(基准值被修改导致死循环)

你原来的终止判断是拿第一个单元格的初始值a和其他单元格比较,但合并时可能会把第一个单元格的cellValue改成其他值(比如把1改成5),这时候a还是初始的1,而所有单元格的值都是5,循环会认为还有不同的值,永远不会终止。

改成直接检查所有单元格的值是否相同就行:

int firstValue = oMaze->array[0]->cellValue;
done = 1;
for(i=0; i<m*n; i++){
    if(oMaze->array[i]->cellValue != firstValue){
        done = 0;
        break; // 只要有一个不同,直接跳出循环,不用遍历全部
    }
}

修正后的核心循环代码示例

把上面的修复点整合后,核心循环部分大概是这样:

int done=0;
while(done==0) {
    int nbAl = rand_a_b(0, m*n); // 选0到m*n-1的单元格
    int wallChoosen = rand_a_b(1, 2); // 假设已经修复了rand_a_b函数

    if(wallChoosen == 1) {
        // 处理上方墙:不是第一行的单元格
        if(nbAl >= n) { 
            int aboveIndex = nbAl - n;
            int oldValue = oMaze->array[aboveIndex]->cellValue;
            int newValue = oMaze->array[nbAl]->cellValue;
            if(oldValue != newValue) {
                oMaze->array[nbAl]->wallAbove = 0;
                // 统一把大值合并到小值,避免基准值混乱
                int target = oldValue < newValue ? oldValue : newValue;
                int source = oldValue < newValue ? newValue : oldValue;
                for(i=0; i<m*n; i++){
                    if(oMaze->array[i]->cellValue == source){
                        oMaze->array[i]->cellValue = target;
                    }
                }
            }
        }
    } else if(wallChoosen == 2) {
        // 处理左侧墙:不是每行第一个的单元格
        if(nbAl % n != 0) { 
            int leftIndex = nbAl - 1;
            int oldValue = oMaze->array[leftIndex]->cellValue;
            int newValue = oMaze->array[nbAl]->cellValue;
            if(oldValue != newValue) {
                oMaze->array[nbAl]->wallLeft = 0;
                int target = oldValue < newValue ? oldValue : newValue;
                int source = oldValue < newValue ? newValue : oldValue;
                for(i=0; i<m*n; i++){
                    if(oMaze->array[i]->cellValue == source){
                        oMaze->array[i]->cellValue = target;
                    }
                }
            }
        }
    }

    // 检查是否所有单元格值相同
    int firstValue = oMaze->array[0]->cellValue;
    done = 1;
    for(i=0; i<m*n; i++){
        if(oMaze->array[i]->cellValue != firstValue){
            done = 0;
            break;
        }
    }
}

把这些修复点都改完后,你的代码应该就能正常生成迷宫,不会死循环,断点也能正常触发了。

内容的提问来源于stack exchange,提问作者Sam Paciência

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:55:33