[英]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.