我目前在处理制作递归分割迷宫生成算法,我想我差不多了。我目前有一个二维阵列,20个细胞宽,15个细胞高。该数组包含单元格对象,它包含行,列和布尔变量,以指示它是否为墙。
什么时候取消注释
generateMaze(height, maxWidth-randomColumn, 1, randomColumn+1);
我得到一个stackoverflow。没有它,它只会向左和向上移动,我需要让它正向和向下移动。我已经长时间盯着这个找出原因,但却看不到这样做。
编辑:我现在可以生成一些内容,但迷宫经常被阻止,也就是说,有些路径被阻止了。因此,如果我设置一个随机起始位置,它可能会被墙包围。 private void generateMaze(int minColumn, int maxColumn, int minRow, int maxRow){
int width = maxColumn - minColumn;
int height = maxRow-minRow;
if (width > 2 && height > 2){
if ("VERTICAL".equals(getOrientation(height, width))){
splitVertical(minColumn, maxColumn, minRow, maxRow);
}
else{
splitHorizontal(minColumn, maxColumn, minRow, maxRow);
}
}
}
private void splitVertical (int minColumn, int maxColumn, int minRow, int maxRow){
int randomColumn = getRandomNumber(minColumn, maxColumn);
for (int i= minRow; i < maxRow; i++){
maze[i][randomColumn] = new Cell (i+1, randomColumn+1, true);
}
maze[(getRandomNumber(minRow, maxRow))][randomColumn].setWall(false);
generateMaze(minColumn, randomColumn, minRow, maxRow);
generateMaze(randomColumn, maxColumn, minRow, maxRow);
}
private void splitHorizontal (int minColumn, int maxColumn, int minRow, int maxRow){
int randomRow = getRandomNumber(minRow, maxRow);
for (int i = minColumn; i < maxColumn; i++){
maze[randomRow][i] = new Cell (randomRow+1, i+1, true);
}
generateMaze(minColumn, maxColumn, minRow, randomRow);
generateMaze(minColumn, maxColumn, randomRow, maxRow);
}
private String getOrientation(int height, int width) {
Random rand = new Random();
if (height > width){
return "HORIZONTAL";
} else if (width > height){
return "VERTICAL";
} else {
int randomNumber = rand.nextInt(2);
if (randomNumber == 0){
return "HORIZONTAL";
} else{
return "VERTICAL";
}
}
}
private int getRandomNumber(int x, int y){
int minimum = x;
int maximum = y;
int randomNumber = 0;
Random rand = new Random();
randomNumber = rand.nextInt((maximum-minimum)+1)+ minimum;
return randomNumber;
}
}
答案 0 :(得分:0)
如果代码无限添加一些调试打印,则可以看到回顾的进度。似乎宽度和高度没有正确更新。也许你错误地计算了尺寸?
我没有完全检查算法,但一般问题是没有停止条件。
在递归函数中,你总是递归。那是错的,你必须检查你是否还需要再做一步。
如果您遇到问题,在递归函数中,您必须检查您剩下的板是否仍然可以被整除。如果你在函数中剩下1x1网格,它就是死路。
答案 1 :(得分:0)
在以下行中取消注释:
generateMaze(height, maxWidth-randomColumn, 1, randomColumn+1);
您正在使用允许值内的随机值调用递归函数,因此它将无限递归,因为大小不会减小,因此您永远不会满足停止条件:
if (height >= 2 && width >= 2)
为什么用随机值调用它?也许正如jnovacho建议的那样,你应该添加另一个条件,例如,最大递归级别或类似的东西......
作为建议,尝试在Eclipse中调试代码,如果可能的话,添加一些UnitTests来检查您测试的配置是否仍然有用......
答案 2 :(得分:0)
您的新代码要好得多,但仍存在问题:
splitHorizontal
。i <= maxRow
和i <= maxColumn
,而不是严格小于创建墙壁时。正如其他人所说,你的递归是不正确的。您要拆分的尺寸没有正确收缩。你有时也会忽略你传递的信息。
丢弃最小高度和宽度并替换为1
,宽度将被丢弃并替换为maxWidth
:
generateMaze(height, randomColumn-1, 1, 1);
//generateMaze(height, maxWidth-randomColumn, 1, randomColumn+1);
当第二个调用被注释时,宽度或高度最终会随机下降到2
以下,从而结束递归。但是,当取消注释时,这两个调用中的一个肯定会有width >= 2
(从maxWidth == 18 > 3
开始)。递归很有可能在早期结束,但仅仅是因为你还没有在"HORIZONTAL"
情况下以"VERTICAL"
案例的相同(不正确)方式实现第二次递归调用
您的代码中似乎有一些关于参数height
,width
,mHeight
和mWidth
的确切含义的混淆。另一组功能可以帮助您解释它:
private void generateMaze(int startRow, int startCol, int endRow, int endCol){
//...
}
专注于"VERTICAL"
案例。您为墙选择的列不尊重分区:
int randomColumn = getRandomNumber(mWidth, maxWidth);
mWidth
始终 1,maxWidth
始终 18,即使您已经进行了分区。同样地,您可能将间隙放在墙外:
for (int i = minHeight; i <= height; i++){
maze[i][randomColumn] = new Cell (i+1, randomColumn+1, true);
}
//Make random passage in the column
maze[rand.nextInt(height)+1][randomColumn].setWall(false);
rand.nextInt(height)+1
可能小于minHeight
。
还有其他一些潜在的问题:
enum
对string
的返回值比getOrientation
更有意义。height
或width
高于其阈值时,递归应该继续,不仅