迷宫生成stackoverflow错误

时间:2014-05-28 12:37:44

标签: java if-statement stack-overflow maze

我正在制作我的迷宫游戏,我几乎得到了迷宫的产生。我遇到的唯一问题是,当我尝试运行我的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;
}
}

我仔细检查了一切,但我找不到问题的原因。当我在else{if(!corstack.isempty)}语句之后放置if(corList.size() > 0)部分时,问题就出现了,所以我知道它在某处。

堆栈跟踪:

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)

4 个答案:

答案 0 :(得分:3)

您在carveMaze()内呼叫carveMaze(),这会导致StackOverflowError。每次调用该方法时,其变量占用堆栈中的空间,这些方法在方法完成时进行垃圾收集。在您的情况下,在方法完成之前,您再次调用它,因此您的堆栈在有空的时间之前会被填满。您的堆栈已满(“溢出”),因此错误。如果你想连续打电话给carveMaze(),你最好选择某种循环。

答案 1 :(得分:1)

看起来你的程序在没有任何基本条件的情况下递归地调用carveMaze()因此你得到了StackOverFlow问题。你可以确定这个函数应该停止调用自己的情况。请找一个例子here < / p>

答案 2 :(得分:1)

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

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

尝试精确定位(使用调试器)为什么这些最小的迷宫没有找到终止条件(即,递归调用将停止发生的情况)。这可能很难做到,但如果您使用可重复性最低的示例 - 即。非常小的迷宫。

有时它也可以帮助将一些条件块放入你的源中,只允许你设置一个只有在满足条件时才能触发的断点(即允许你在列表小于一定大小时中断)例子)。

一旦你让它为某些迷宫工作,单元测试代码的每一部分都是一种很好的方法,可以确保特殊情况(“极端情况”)不会导致你的代码在看似随意的场合下脱轨。

一旦小例子成功地为许多输入工作,您就可以开始创建更大的迷宫。如果堆栈溢出只在 上发生在非常大的迷宫上,那么它可能只是堆栈大小的问题。

此时,如果这似乎肯定是问题,请尝试增加您的Java堆栈大小:

java -Xss4m Test

了解更多信息,请点击此处:How to increase the Java stack size?

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

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

Way to go from recursion to iteration

我认为最重要的一点是,使用调试器调试代码比阅读它更容易,这使得作为代码编写者的人能够最好地修复它。

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

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

答案 3 :(得分:0)

我发现它:)错误是随机新邻居的获得。我在邻居列表中插入了x,y,x,y,x,y等坐标,然后选择了随机坐标。而不是得到x和跟随y,我选择随机x随机y:0

谢谢大家!