繁体   English   中英

迷宫产生stackoverflow错误

[英]Maze generating stackoverflow error

我正在迷宫游戏中工作,几乎可以产生迷宫了。 我唯一的问题是,当我尝试运行init方法时,它给了我一个堆栈溢出错误。 我认为这与corStack太大有关,但是我找不到导致此问题的原因。 这是代码:

迷宫产生:

public void carveMaze(Stack<Integer> corStack, int currentX, int currentY)
{
    ArrayList<Integer> corList = getNeighbours(currentX, currentY);
    Random randomGen = new Random();

    while (checkForUnvisited()) {enter code here
        if (corList.size() > 0) {

            boolean goodNumber = false;
            int newY = 0;
            int newX = 0;
            int index = 0;

            index = randomGen.nextInt(corList.size());
            if (index % 2 != 0) {
                newY = corList.get(index);
                goodNumber = true;
            }

            goodNumber = false;
            while (!goodNumber) {
                index = randomGen.nextInt(corList.size());
                if (index % 2 == 0) {
                    newX = corList.get(index);
                    goodNumber = true;
                }
            }

            corStack.push(currentY);
            corStack.push(currentX);

            if (newX > currentX) {
                maze[newY][newX - 1].setStatus(Cell.WEG);
                maze[newY][newX - 1].setVisited(true);
                maze[newY][newX].setVisited(true);
            } else if (newX < currentX) {
                maze[newY][newX + 1].setStatus(Cell.WEG);
                maze[newY][newX + 1].setVisited(true);
                maze[newY][newX].setVisited(true);
            } else if (newY > currentY) {
                maze[newY - 1][newX].setStatus(Cell.WEG);
                maze[newY - 1][newX].setVisited(true);
                maze[newY][newX].setVisited(true);
            } else if (newY < currentY) {
                maze[newY + 1][newX].setStatus(Cell.WEG);
                maze[newY + 1][newX].setVisited(true);
                maze[newY][newX].setVisited(true);
            }

            maze[currentY][currentX].setVisited(true);
            currentX = newX;
            currentY = newY;
            carveMaze(corStack, currentX, currentY);
        } else {
            if (!corStack.isEmpty()) {
                currentX = (int) corStack.pop();
                currentY = (int) corStack.pop();
                carveMaze(corStack, currentX, currentY);
            }
        }

    }

}

单元格类别:

package javaapplication23;
public class Cell {

public static final int SPELER = 2;
public static final int WEG = 0;
public static final int MUUR = 1;
public static final int BAZOOKA = 3;

private int status;
private boolean visited;

Cell(int status, boolean visited)
{
    this.status = status;
    this.visited = visited;
}

public int getStatus()
{
    return status;
}

public boolean getVisited()
{
    return visited;
}

public void setStatus(int status)
{
    this.status = status;
}

public void setVisited(boolean visited)
{
    this.visited = visited;
}
}

我仔细检查了所有内容,但找不到问题的原因。 当我在if(corList.size() > 0)语句之后放置else{if(!corstack.isempty)}部分时,问题就开始了,所以我知道它在那儿。

堆栈跟踪:

Exception in thread "main" java.lang.StackOverflowError
at java.util.ArrayList.grow(ArrayList.java:239)
at java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:220)
at java.util.ArrayList.ensureCapacityInternal(ArrayList.java:212)
at java.util.ArrayList.add(ArrayList.java:443)
at javaapplication23.MazeManager.getNeighbours(MazeManager.java:154)
at javaapplication23.MazeManager.carveMaze(MazeManager.java:55)
at javaapplication23.MazeManager.carveMaze(MazeManager.java:110)
at javaapplication23.MazeManager.carveMaze(MazeManager.java:105)
at javaapplication23.MazeManager.carveMaze(MazeManager.java:110)
at javaapplication23.MazeManager.carveMaze(MazeManager.java:105)
at javaapplication23.MazeManager.carveMaze(MazeManager.java:110)
at javaapplication23.MazeManager.carveMaze(MazeManager.java:105)
at javaapplication23.MazeManager.carveMaze(MazeManager.java:110)
at javaapplication23.MazeManager.carveMaze(MazeManager.java:105)
at javaapplication23.MazeManager.carveMaze(MazeManager.java:110)
at javaapplication23.MazeManager.carveMaze(MazeManager.java:105)
at javaapplication23.MazeManager.carveMaze(MazeManager.java:110)
at javaapplication23.MazeManager.carveMaze(MazeManager.java:105)
at javaapplication23.MazeManager.carveMaze(MazeManager.java:110)
at javaapplication23.MazeManager.carveMaze(MazeManager.java:105)
at javaapplication23.MazeManager.carveMaze(MazeManager.java:110)
at javaapplication23.MazeManager.carveMaze(MazeManager.java:105)
at javaapplication23.MazeManager.carveMaze(MazeManager.java:110)
at javaapplication23.MazeManager.carveMaze(MazeManager.java:105)
at javaapplication23.MazeManager.carveMaze(MazeManager.java:110)
at javaapplication23.MazeManager.carveMaze(MazeManager.java:105)
at javaapplication23.MazeManager.carveMaze(MazeManager.java:110)

您呼叫carveMaze()carveMaze()这将导致StackOverflowError 每次调用该方法时,其变量都会占用堆栈中的空间,该变量将在方法完成时进行垃圾回收。 在您的情况下,在方法完成之前,您要再次调用它,因此,在有时间清空之前,堆栈会被更多地填充。 您的堆栈已满(“溢出”),因此出现错误。 如果要连续调用carveMaze() ,最好使用某种循环。

看起来您的程序正在递归调用carveMaze()而没有任何基本条件,因此您遇到了StackOverFlow问题。能否确定此函数应停止自行调用的情况。请在此处找到示例

在更改代码结构时遇到任何麻烦之前,您需要确保算法实现中没有错误的逻辑。 这只是部分说明了显而易见的内容,但值得一提:

尝试使用最小大小的迷宫代码,看看它们是否完整完成而不会溢出。 如果它们始终有效,那么您的逻辑可能就不错了 如果没有,那么在为递归循环找到退出条件时会有错误的逻辑(这将每次都保证溢出)。

尝试查明(使用调试器)为什么这些最小的迷宫没有找到终止条件(即,递归调用将停止发生的情况)。 这可能很难做到,但是如果您使用最少的可重现示例(例如。 很小的迷宫。

有时,将某些条件块放入源中也可以帮助您仅设置一个断点,该断点仅在满足条件时才能触发(例如,允许您在列表小于一定大小时中断)。

一旦使它工作起来令人迷惑,对代码的每个部分进行单元测试是确保特殊情况(“角落情况”)不会导致代码在看似随意的情况下脱轨的好方法。

一旦小示例成功地用于许多输入,您就可以开始创建更大的迷宫。 如果堆栈溢出在非常大的迷宫中发生,则可能只是堆栈大小的问题。

到那时,如果这绝对是问题所在,请尝试增加Java堆栈大小:

java -Xss4m Test

有关更多信息,请参见此处: 如何增加Java堆栈大小?

如果增加堆栈大小可以解决问题,那么一切都可能很好:您可以通过每次运行代码时增加堆栈大小来解决问题,或者更改代码以删除递归,但是至少您会知道逻辑确实找到了终止条件,最终给了足够的内存资源来使用。

删除递归的一般方法是使用循环和您自己的Stack数据结构,而不是虚拟机的堆栈。 此处的更多信息:

从递归到迭代的方法

我认为最重要的一点是,调试器比仅通过阅读调试器更容易完成调试,这使您(编写代码的人)处于最佳修复状态。

此外,调试代码通常比编写问题要求其他人提供帮助更有趣。

希望这些想法能帮助您解决问题。

我发现了:)问题在于随机的新邻居。 我在邻居列表中插入了x,y,x,y,x,y等坐标,然后选择了随机坐标。 而不是得到x并跟随y,我选择了一个随机x,其中随机y:0

谢谢大家!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM