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