学完java,需要做一个迷宫设计,我想着好不容易写出来了,也得记录一下。
一、迷宫生成
采用递归分割法随机生成迷宫地图,我们需要先确定迷宫的大小,高度和宽度必须是奇数。为了保证一行墙壁一行通路,大小只能是奇数。最外层墙壁不属于迷宫,是在给定高和宽基础上添加的两行两列。根据给定的高和宽生成一个初始迷宫,初始迷宫只是在没有任何阻碍的迷宫外侧添加一圈墙壁
在初始迷宫的基础上,随机选择一行和一列,将其置成墙壁,将迷宫分成独立的四部分。这里需要注意一点,为了满足一行墙壁一行通路的条件,我们需要在偶数行置墙壁(忽略外部墙壁,下标从1开始)。
为了保持迷宫的连通性,我们需要在上一步生成的四堵墙壁上开几个洞。可以看出,开一个洞和两个洞都不能保证迷宫的连通性,而开四个洞又使迷宫通路过多,所以我们随机选择三堵墙开洞。和生成墙壁相反,开洞的位置在奇数行。
在完成上面三步之后,我们就生成了四个小迷宫,然后对小迷宫执行上面的两步直到迷宫高度或宽度为1为止。最终就会生成图一所示的迷宫。
特别说明:为了生成的迷宫不止一条路,我在每一面墙上随机开了三个洞。
/*
* 迷宫生成算法,采用递归方式实现,随机画横竖两条线,然后在线上随机开三扇门
* x:迷宫起点的x坐标
* y:迷宫起点的y坐标
* height:迷宫的高度
* width:迷宫的宽度
*/
private void getdoor(int x1, int y1, int x2, int y2) {
if (x1 == x2) {
int pos = y1 +r.nextInt((y2 - y1 )/2+1)*2;//在奇数位置开门
m[x1][pos] =0;
}
else if (y1 == y2) {
int pos =x1 +r.nextInt((x2 - x1 )/2+1)*2;
m[pos][y1] =0;
}
}
private void getMaze(int x, int y, int col, int row) {
int x1, y1;
if (col<=2||row<=2)
return;
//横着画线,在偶数位置画线
x1=x+(int)(Math.random()*(col/2))*2+1;
for (int i = y; i < y +row;i++) {
m[x1][i] = 1;
}
//竖着画一条线,在偶数位置画线
y1=y+(int)(Math.random()*(row/2))*2+1;
for (int i = x; i < x +col; i++) {
m[i][y1] =1;
}
//随机开三扇门,左侧墙壁为1,逆时针旋转
int d =(int)(Math.random()*4) + 1;//随机产生四个数;
//为了防止出现死路,随机在一道墙上开两个洞
switch (d)
{
case 1:
getdoor(x1+1, y1, x + col - 1, y1);// 在第2道墙上开洞
getdoor(x1, y1+1, x1, y +row-1);// 在第三个墙上开洞
getdoor(x, y1, x1-1, y1);// 在第四个墙上开洞
getdoor(x1+1, y1, x+col-1, y1);// 在第2道墙上开洞
getdoor(x1, y1+1, x1, y +row - 1);// 在第3道墙上开洞
getdoor(x, y1, x1-1, y1);// 在第4道墙上开洞
break;
case 2:
getdoor(x1, y1 + 1, x1, y + row - 1);// 在第三道墙上开洞
getdoor(x, y1, x1-1, y1);// 在第四道墙上开洞
getdoor(x1, y, x1, y1-1);// 在第1道墙上开洞
getdoor(x1, y1+ 1, x1, y + row - 1);// 在第3道墙上开洞
getdoor(x, y1, x1 - 1, y1);// 在第4道墙上开洞
getdoor(x1, y, x1, y1 - 1);// 在第1道墙上开洞
break;
case 3:
getdoor(x, y1, x1 - 1, y1);// 在第4道墙上开洞
getdoor(x1, y, x1, y1 - 1);// 在第1道墙上开洞
getdoor(x1 + 1, y1, x + col - 1, y1);// 在第2道墙上开洞
getdoor(x, y1, x1 - 1, y1);// 在第四道墙上开洞
getdoor(x1, y, x1, y1 - 1);// 在第一道墙上开洞
getdoor(x1 + 1, y1, x + col - 1, y1);// 在第2道墙上开洞
break;
case 4:
getdoor(x1, y, x1, y1 - 1);// 在第一道墙上开洞
getdoor(x1 + 1, y1, x + col - 1, y1);// 在第2道墙上开洞
getdoor(x1, y1 + 1, x1, y +row - 1);// 在第三道墙上开洞
getdoor(x1, y, x1, y1 - 1);// 在第一道墙上开洞
getdoor(x1 + 1, y1, x + col- 1, y1);// 在第2道墙上开洞
getdoor(x1, y1 + 1, x1, y + row - 1);// 在第三道墙上开洞
break;
default:
break;
}
// 左上角的方框
getMaze(x, y, x1-x, y1-y);
// 右上角的方框
getMaze(x, y1+1,x1-x,row-y1+y-1);
// 左下角的方框
getMaze(x1+1,y,col-x1+ x-1,y1-y);
// 右下角方框
getMaze(x1+1, y1+1, col-x1+x-1, row-y1+y-1);
}