使用prim算法随机构造迷宫
对于一个n*m的地图,我们可以先对地图进行初始化,如图。
地图中黑色区域代表墙壁,白色代表通路,橙色代表可以挖开的墙壁
所以,我们可以对已经连接的通路,随机凿开四周橙色的墙壁,最终的通路便是我们想要的迷宫。
首先,我们选择一个白色单元格作为起点(点B)
然后把他的邻墙A放入列表。然后在所有的列表中,随机挑选一堵墙壁,将其打通(变成通路),并得到新的起点B。
再反复将B的邻墙加入列表,随机打破,反复进行。
当一堵墙的两侧,均变成连起来的通路时。为了避免出现回路,我们将该墙从列表中移除,使其不可能被打破
综上规律,最终我们便可以得到一个随机的迷宫。
参考视频
不过,该方法好像只能生成奇数尺寸的(n和m)均为奇数
自己写的一个巨丑无比的代码
#include<bits/stdc++.h>
using namespace std;
char mp[1000][1000];
int nex[4][2]={{1,0},{-1,0},{0,1},{0,-1}},vis[1000][1000];
struct wz
{
int x,y;
}w;
int main()
{
int n,m;
scanf("%d%d",&n,&m);
memset(mp,'0',sizeof(mp));
memset(vis,0,sizeof(vis));
for(int i=2;i<=n-1;i++)
{
if(i%2==0)
for(int j=2;j<=m-1;j+=2)
{
mp[i][j]='1';
}
}
for(int i=1;i<=n;i++)
{
for(int j=(i%2==0)?1:2;j<=m;j+=2)
if(mp[i][j]=='0')
mp[i][j]='2';
}
vector<wz>q;
w.x=1;w.y=2;
q.push_back(w);
w.x=2;w.y=1;
q.push_back(w);
vis[1][1]=1;
srand((unsigned)time(NULL));
while(!q.empty())
{
int num=q.size();
int nn=rand()%num;
if(vis[q[nn].x+1][q[nn].y] && vis[q[nn].x-1][q[nn].y])
{
q.erase(q.begin()+nn);continue;
}
if(vis[q[nn].x][q[nn].y+1] && vis[q[nn].x][q[nn].y-1])
{
q.erase(q.begin()+nn);continue;
}
mp[q[nn].x][q[nn].y]='0';
int x,y;
for(int op=0;op<4;op++)
{
x=q[nn].x+nex[op][0],y=q[nn].y+nex[op][1];
if(vis[x][y]==0 && x>=1 && x<=n && y>=1 && y<=m && mp[x][y]=='0')
{
vis[x][y]=1;break;
}
}
for(int op=0;op<4;op++)
{
if(mp[x+nex[op][0]][y+nex[op][1]]=='2')
{
w.x=x+nex[op][0];w.y=y+nex[op][1];
q.push_back(w);
}
}q.erase(q.begin()+nn);
}
for(int j=1;j<=m+2;j++)
printf("-");
printf("\n");
for(int i=1;i<=n;i++)
{
printf("|");
for(int j=1;j<=m;j++)
{
if(mp[i][j]!='0')
printf("#");
else
printf(".");
}
printf("|\n");
}
for(int j=1;j<=m+2;j++)
printf("-");
}