迷宫生成及寻路右手贴墙 C++实现.docx
- 文档编号:2200294
- 上传时间:2022-10-27
- 格式:DOCX
- 页数:15
- 大小:18.62KB
迷宫生成及寻路右手贴墙 C++实现.docx
《迷宫生成及寻路右手贴墙 C++实现.docx》由会员分享,可在线阅读,更多相关《迷宫生成及寻路右手贴墙 C++实现.docx(15页珍藏版)》请在冰豆网上搜索。
迷宫生成及寻路右手贴墙C++实现
//采用深度优先遍历生成迷宫,优点:
生成的迷宫肯定会有通路,且效果不错。
缺点:
迷宫的长宽只能为奇数
//右手贴墙走进行迷宫寻路,不一定是最短路径,在迷宫无通路时会返回入口点
#include
#include
#include
#include
usingnamespacestd;
//对于每一格,1代表墙,0代表可走
classMazeCell//定义一个节点,每个节点代表一个固定可以通过的格子,每个节点有四堵墙
{
friendclassmaze;//将迷宫对象声明为节点的友元
public:
MazeCell()
{
x=y=0;
for(inti=0;i<4;i++)
wall[i]=1;//0上,1下,2左,3右
isVisit=false;
}
private:
boolisVisit;//节点是否被访问
intx,y;//横纵坐标
intwall[4];//四堵墙
};
classPoint
{
friendclassmaze;
private:
intdirection;//走的方向
//横纵坐标
intx;
inty;
};
classmaze
{
public:
maze(intm=11,intn=11);
voidgenerator();//迷宫生成器
voidprintMaze();//打印迷宫
booljudgeCell(int,int);//判断当前节点的某个相临节点是否能成为下个当前节点
voidbreakWall(MazeCell*);//拆掉两个节点之间墙的函数
voidtravel();//迷宫寻路函数
~maze();//必须要有析构函数清除动态申请内存,防止内存泄露
private:
intstartPoint;//迷宫入口格子开始的横坐标
intendPoint;//迷宫出口格子的纵坐标
introw;//节点矩阵行数
intcolumn;//节点矩阵列数
stack
MazeCell**matrix;//生成迷宫的节点矩阵
inttotal;//节点的总个数
intvisit;//被访问过的节点个数
int**graph;//迷宫图
intgraphRow;//迷宫的行数
intgraphColumn;//迷宫的列数
MazeCell*currentCell;//记录深度优先遍历节点时正在访问的节点
PointgoPoint;//记录迷宫寻路时当前所在位置(格子)的信息
};
//定义走迷宫时的方向,分别为上下左右
constintshang=0;
constintxia=1;
constintzuo=2;
constintyou=3;
maze:
:
maze(intm,intn)
{
while(m%2==0||n%2==0)
{
cout<<"\n输入错误!
请重新输入!
";
cin>>m>>n;
}
visit=0;//访问过的节点数应当初始化为0
//注意最后生成的迷宫与所构造的节点矩阵应当有这样的关系,rowcolumn指的是节点矩阵的行列
row=(m-1)/2;
column=(n-1)/2;
total=row*column;//所有的节点数
srand(time(0));
//初始化节点矩阵
matrix=newMazeCell*[row];
for(inti=0;i { matrix[i]=newMazeCell[column]; } for(inti=0;i for(intj=0;j { matrix[i][j].x=i; matrix[i][j].y=j; } //注意矩阵节点跟迷宫格子的关系 graphRow=m; graphColumn=n; //初始化迷宫 graph=newint*[graphRow]; for(inti=0;i graph[i]=newint[graphColumn]; for(inti=0;i for(intj=0;j graph[i][j]=1; for(inti=0;i { for(intj=0;j graph[2*i+1][2*j+1]=0;//把迷宫中除了代表(矩阵节点及节点相邻的四堵墙)的其他格子弄为墙 } } maze: : ~maze() { for(inti=0;i delete[]matrix[i]; delete[]matrix; for(inti=0;i delete[]graph[i]; delete[]graph; } voidmaze: : printMaze() { for(inti=0;i { for(intj=0;j { if(graph[i][j]==0)//没有走过的格子 cout<<''; elseif(graph[i][j]==1)//墙 cout<<'#'; elseif(graph[i][j]==2) cout<<'o';//第一次走过的格子 else cout<<'x';//第二次走过的格子 } cout< } } voidmaze: : breakWall(MazeCell*tempCell) { intrelation;//存放当前节点与上一个被访问节点的位置关系,下面以此为依据进行拆墙 if(tempCell->x! =currentCell->x)//关系为上下相邻 { relation=tempCell->x-currentCell->x; if(relation==1) currentCell->wall[1]=tempCell->wall[0]=0; else currentCell->wall[0]=tempCell->wall[1]=0; } else//左右相邻 { relation=tempCell->y-currentCell->y; if(relation==1) currentCell->wall[3]=tempCell->wall[2]=0; else currentCell->wall[2]=tempCell->wall[3]=0; } } boolmaze: : judgeCell(intx,inty)//判断当前节点的某个相临节点是否能成为下个当前节点 { //是否有效,木有越界 if(x<0||x>row-1) returnfalse; if(y<0||y>column-1) returnfalse; //是否被访问过 if(matrix[x][y].isVisit) returnfalse; returntrue; } voidmaze: : generator() { intcount1=0,count2=0;//count1为记录前一个被访问节点(堆栈顶部节点)有效相邻节点数,count2为当前访问节点的有效相邻节点数 currentCell=&matrix[0][0];//从0,0开始访问,也可以随机取一个节点 currentCell->isVisit=true;//初始点为0,0,并标记 visit+=1; intcurrentX=currentCell->x; intcurrentY=currentCell->y; MazeCell*tempCell;//存放选好的下一个要访问的节点 while(total>visit)//当还有点没被访问时 { inti=0;//记录有效相邻节点数 MazeCell*temp[4];//存放有效相邻节点的数组 if(judgeCell(currentX+1,currentY)) { temp[i]=&matrix[currentX+1][currentY]; i++; } if(judgeCell(currentX-1,currentY)) { temp[i]=&matrix[currentX-1][currentY]; i++; } if(judgeCell(currentX,currentY+1)) { temp[i]=&matrix[currentX][currentY+1]; i++; } if(judgeCell(currentX,currentY-1)) { temp[i]=&matrix[currentX][currentY-1]; i++; } if(visit==0) count2=i; else { inttempp; tempp=count2; count2=i; count1=tempp; } if(i>0) { ints=rand()%i;//从有效相邻节点中随机选取一个出来作为下一个要访问的节点 tempCell=temp[s]; breakWall(tempCell);//拆墙 mazeStack.push(*currentCell);//将上一个节点进栈 currentCell=tempCell; currentCell->isVisit=true; visit++; currentX=currentCell->x; currentY=currentCell->y; } else { if(! mazeStack.empty()&&count1>1)//当前节点无有效的相邻节点,并且前一个节点并非仅仅只有当前节点一个有效相邻节点(避免死循环)原路返回,返回到上一个节点 { currentCell->isVisit=false; visit--; currentCell=&mazeStack.top(); mazeStack.pop(); } else//如若上一个被访问节点只有当前节点一个有效相邻节点,则从所有被访问过的节点中随机选取一个作为当前节点(从路径展开分支,保证路径不会断) { mazeStack.push(*currentCell); inta1=rand()%row,a2=rand()%column; while(! matrix[a1][a2].isVisit)
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 迷宫生成及寻路右手贴墙 C+实现 迷宫 生成 右手 C+ 实现
![提示](https://static.bdocx.com/images/bang_tan.gif)