我尝试使用深度优先搜索算法创建迷宫,并且我尝试使用堆栈和递归算法,并且我在先前的示例中测试了算法并且它们工作正常但我无法做到让它与迷宫一起工作。我也认为我展示迷宫的方式是错误的。
public void depthFirstSearch(){
for(int row = 0; row < dim; row++){
for(int column = 0; column < dim; column++){
Node current = maze[row][column];
if(!current.isVisited()){
search(current);
}
}
}
}
public void search(Node node){
node.visit();
Random rand = new Random();
int direction = rand.nextInt(4);
//west wall
if(direction == 0 && left(node) != null && !left(node).isVisited()){
node.breakLeft();
left(node).breakRight();
search(left(node));
}
//east wall
if(direction == RIGHT_DIRECTION && right(node) != null && !right(node).isVisited()){
node.breakRight();
right(node).breakLeft();
search(right(node));
}
//south wall
if(direction == BOTTOM_DIRECTION && down(node) != null && !down(node).isVisited())
{
node.breakDown();
down(node).breakUp();
search(down(node));
}
//north wall
if(direction == TOP_DIRECTION && up(node) != null && !up(node).isVisited()){
node.breakUp();
up(node).breakDown();
search(up(node));
}
}
public char[][] fillMaze(){
depthFirstSearch();
char[][] filledMaze = new char[dim][dim];
for(int row = 0; row < dim; row++)
for(int column = 0; column < dim; column++){
//Fill left wall
if(inRange(row, column - 1) && maze[row][column].left && filledMaze[row][column - 1] != '#')
filledMaze[row][column - 1] = '#';
//Fill top wall
if(inRange(row - 1, column) && maze[row][column].up && filledMaze[row - 1][column] != '#')
filledMaze[row - 1][column] = '#';
//Fill right wall
if(inRange(row, column + 1) && maze[row][column].right && filledMaze[row][column + 1] != '#')
filledMaze[row][column + 1] = '#';
//Fill bottom wall
if(inRange(row + 1, column) && maze[row][column].down && filledMaze[row + 1][column] != '#')
filledMaze[row + 1][column] = '#';
}
return filledMaze;
}
public void drawMaze(char[][] filledMaze){
for(int row = 0; row < dim; row++){
for(int column = 0; column < dim; column++){
if(filledMaze[row][column] != '#') {
System.out.print(" ");
}
else {
System.out.print("#");
}
}
System.out.println();
}
}
输出10x10迷宫,其中|代表一堵墙,这里迷宫基本上都是墙壁:
||||||||||
||||||||||
||||||||||
||||||||||
||||||||||
||||||||||
||||||||||
||||||||||
||||||||||
||||||||||
所以迷宫非常密集,如果我切换到dfs的堆叠算法,它会好一点,但我觉得无论是我绘制迷宫的方式还是我的方式都有一些非常错误实现了dfs来创建迷宫..
答案 0 :(得分:1)
问题在于印刷。我尝试了你的DFS实现,它的工作原理,因为我不了解打印的实现,我创建了自己的。
打印的想法是每个Node
都有自己的nodeMat[3][3]
,它将填充#
,即:
###
#
#
之后只需打印整个迷宫:
for (int row = 0; row < matrix.length; row++) {
for (int nodeRow = 0; nodeRow < 3; nodeRow++) {
for (int col = 0; col < matrix.length; col++) {
Node cur = matrix[row][col];
cur.printRow(nodeRow);
if (col == matrix.length - 1)
System.out.println();
}
}
}
迷宫看起来像:
##############################
# ## ## ## ## ## ## ## #
# ########## #### ##########
# ########### ##### #########
# ## ## ## ## ## ## ## #
#### ## ################ ####
### ## ################# ###
# ## ## ## ## ## #
########## ##### ### #######
######### #### ##### ######
# ## ## ## ## ## ## #
####### #### #### ##########
####### ### #### ##########
# ## ## ## ## ## #
###################### ## ####
###################### ## ###
# ## ## ## ## ## ## #
# ##### ## ########### #### #
# ##### ## ########## ##### #
# ## ## ## ## ## ## ## ## #
######################### ## #
######################### ## #
# ## ## ## ## ## ## #
###### #### ########### ####
####### ##### ########## ####
# ## ## ## ## ## ## ## ## #
##############################
##############################
# ## ## ## ## ## ## #
##############################
您看到从一个角落到另一个角落没有单一路径。这是因为当您致电search(node)
时,您只有一次机会找到未访问过的Node
。
我添加了一个list
个数字0,1,2,3
。每个数字是位置LEFT,RIGHT,UP,DOWN。并在课程Node
public boolean randomExist() {
return list.size()>0;
}
public int getRandom() {
int randomNumber = random.nextInt(list.size());
return list.remove(randomNumber);
}
将search(node)
方法更改为:
public void search(Node node) {
node.visit();
while (node.randomExist()) {
int direction = node.getRandom();
if (direction == LEFT && leftOK(node) && !left(node).isVisited()) {
node.breakLeft();
left(node).breakRight();
search(left(node));
return;
}
if (direction == RIGHT && rightOK(node) && !right(node).isVisited()){
node.breakRight();
...
重要的部分是return
声明中的if
声明。
现在迷宫看起来好多了:
##############################
# ## ## ## #
###### ## ### ## #######
####### ##### ## ######
# ## ## ## ## #
# ######## ############# #
# ## ####### ############# #
# ## ## ## ## ## #
# ## ## ####### ## ## ######
# ## ####### ## ## #######
# ## ## ## ## ## ## #
# ######## ## #### ## #### #
# ######## ## ### ## #### #
# ## ## ## ## ## #
# ######## ############# ## #
# ####### ############## ## #
# ## ## ## ## #
###### ##### ###### ## ## #
####### #### ######## ## #
# ## ## ## ## ## #
### #### ## ## ######## #
#### ##### ## ## ####### #
# ## ## ## ## ## ## #
#### ## ######## ########### #
### ## ####### ########## #
# ## ## ## ## #
# ####### ####### ## ######
# ###### ####### ## ######
# ## ## #
##############################