![5976cd1bcd1795ad294053f22dc3063f.png](https://img-blog.csdnimg.cn/img_convert/5976cd1bcd1795ad294053f22dc3063f.png)
- 随机生成迷宫地图
- 通过键盘手动求解生成的迷宫
- MATLAB自动求解生成的迷宫
![717843ad11c54bdcea58b3cb5196c991.gif](https://img-blog.csdnimg.cn/img_convert/717843ad11c54bdcea58b3cb5196c991.gif)
一、深度优先搜索算法
首先来看一下维基百科上对深度优先搜索算法的介绍: 深度优先搜索算法(Depth-First-Search,DFS)[1]是一种用于遍历或搜索树或图的算法。这个算法会尽可能深的搜索树的分支。当节点v的所在边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这一过程一直进行到已发现从源节点可达的所有节点为止。如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问为止。![15f2ec90a0d09264b880f9a7d617bb3c.png](https://img-blog.csdnimg.cn/img_convert/15f2ec90a0d09264b880f9a7d617bb3c.png)
Step 1.设置一个起点。将起点作为当前迷宫单元,并标记为已访问 Step 2.当还存在未标记的迷宫单元时,进行循环 (1)如果当前迷宫单元有未被访问过的相邻的迷宫单元 ① 随机选择一个未访问的相邻迷宫单元 ② 将当前迷宫单元入栈 ③ 移除当前迷宫单元与相邻迷宫单元的墙 ④ 标记相邻迷宫单元已访问,并用它作为当前迷宫单元 (2)如果当前迷宫单元不存在未访问的相邻迷宫单元,并且栈不空 ① 栈顶的迷宫单元出栈 ② 令其成为当前迷宫单元
下面我们通过一个简单的栗子,来理解一下深度优先搜索算法。如下图所示, 从图中的 V0(顶点)出发,是否存在一条路径长度为4的搜索路径。
![0a329f53763a28c2fc85ca222d1ec7ca.png](https://img-blog.csdnimg.cn/img_convert/0a329f53763a28c2fc85ca222d1ec7ca.png)
![8262df3f37bf1b28c58fb6d7fd1f4061.png](https://img-blog.csdnimg.cn/img_convert/8262df3f37bf1b28c58fb6d7fd1f4061.png)
![30493493787b9b9ead8cefa1a8ad5ab6.png](https://img-blog.csdnimg.cn/img_convert/30493493787b9b9ead8cefa1a8ad5ab6.png)
![ecf60eda5d66615eac82e68384be1fd9.png](https://img-blog.csdnimg.cn/img_convert/ecf60eda5d66615eac82e68384be1fd9.png)
![30493493787b9b9ead8cefa1a8ad5ab6.png](https://img-blog.csdnimg.cn/img_convert/30493493787b9b9ead8cefa1a8ad5ab6.png)
![8262df3f37bf1b28c58fb6d7fd1f4061.png](https://img-blog.csdnimg.cn/img_convert/8262df3f37bf1b28c58fb6d7fd1f4061.png)
![bc9fc180e2e5dc48b3412f7977b12029.png](https://img-blog.csdnimg.cn/img_convert/bc9fc180e2e5dc48b3412f7977b12029.png)
![394ee9dc61e86a543abdddf2e4d09810.png](https://img-blog.csdnimg.cn/img_convert/394ee9dc61e86a543abdddf2e4d09810.png)
![bc9fc180e2e5dc48b3412f7977b12029.png](https://img-blog.csdnimg.cn/img_convert/bc9fc180e2e5dc48b3412f7977b12029.png)
![859e4a7f181c94a36d196b4f52f0de16.png](https://img-blog.csdnimg.cn/img_convert/859e4a7f181c94a36d196b4f52f0de16.png)
![c9b299cbe30a64c4e7efabe1674080a9.png](https://img-blog.csdnimg.cn/img_convert/c9b299cbe30a64c4e7efabe1674080a9.png)
二、生成迷宫游戏的地图
借助前面介绍的深度优先搜索算法可以生成迷宫游戏的地图。深度优先搜索算法构建迷宫的思想就是,每次把新找到的未访问迷宫单元作为起始点,寻找与其相邻的未访问过的迷宫单元,直到所有的单元都被访问到。也就是从起点开始随机走,走不通了就返回上一步,从下一个能走的地方再开始随机走。 首先,我们生成迷宫游戏的地图的数据矩阵,MATLAB代码如下:function map=maze(a,b)
map=zeros(a,b);
map(2,1)=1;
map(a-1,b)=1;
p=zeros(1,4);
q=zeros(1,a*b);
i=2;j=2;
x=0;
while ~isempty(find(map(2:2:a,2:2:b)==0,1))
t=0;
map(i,j)=1;
if i>2
if map(i-2,j)==0
t=t+1;p(t)=1;
end
end
if i
if map(i+2,j)==0
t=t+1;p(t)=4;
end
end
if j>2
if map(i,j-2)==0
t=t+1;p(t)=2;
end
end
if j
if map(i,j+2)==0
t=t+1;p(t)=3;
end
end
if t==0
q(x)=5-q(x);
else
x=x+1;
q(x)=p(randi(t));
end
switch q(x)
case 1
i=i-2;map(i+1,j)=1;
case 4
i=i+2;map(i-1,j)=1;
case 2
j=j-2;map(i,j+1)=1;
case 3
j=j+2;map(i,j-1)=1;
end
if t==0
x=x-1;
end
后台回复关键词【迷宫】获得完整代码 说明:map矩阵中的0元素代表未打通的墙壁,其余元素代表可行域(即通道)。 通过运行上述代码,可以生成迷宫游戏的地图数据矩阵,下面我们来看一下如何进行数据可视化,即绘制迷宫游戏的地图。MATLAB绘制迷宫游戏主要借助line函数,因此,先来看一下line函数的主要功能,在MATLAB的命令窗口中输入help line可以看到如下说明:![2a387b4d07d06a0b6a91bacac19a15ef.png](https://img-blog.csdnimg.cn/img_convert/2a387b4d07d06a0b6a91bacac19a15ef.png)
![ef0b008ce25413bd240f15fb7da27dff.png](https://img-blog.csdnimg.cn/img_convert/ef0b008ce25413bd240f15fb7da27dff.png)
![97197e6227512bb2fa2c98db9219f6b1.png](https://img-blog.csdnimg.cn/img_convert/97197e6227512bb2fa2c98db9219f6b1.png)
![d67c4d3e459db345e33c274d8f9e4973.png](https://img-blog.csdnimg.cn/img_convert/d67c4d3e459db345e33c274d8f9e4973.png)
function time=map_draw(map,str)
global nar FIGURE;
[e,f]=size(map);
set(FIGURE,'position',get(0,'ScreenSize'));
axis off
set(gca,'YDir','reverse')
if nar<1
map(map==2)=3;
end
for i=1:e
for j=1:f
if map(i,j)==0
if nar<1
if(mod(i,2)>mod(j,2))
line([max(j-1,1),min(j+1,f)],[i,i]);
elseif(mod(i,2)
line([j,j],[max(i-1,1),min(i+1,e)]);
end
else
if map(i,max(j-1,1))==0&&j>1
line([max(j-1,1),j],[i,i]);
end
if map(i,min(j+1,f))==0&&j
line([j,min(j+1,f)],[i,i]);
end
if map(max(i-1,1),j)==0&&i>1
line([j,j],[max(i-1,1),i]);
end
if map(min(i+1,e),j)==0&&i
line([j,j],[i,min(i+1,e)]);
end
end
elseif map(i,j)==2 || map(i,j)==3
imagesc(map)
colormap([0,0,0;1,1,1;0,1,0;1,0,0])
axis off
end
end
end
g=gcf;
set(g.Children,'position',[0.1 0.1 0.8 0.8])
set(g,'position',get(0,'ScreenSize'));
text(0.4*f,-1,str);
后台回复
关键
词【
迷宫
】获得完整代码
下面使用上述函数绘制10×10的迷宫地图,来看一下效果如何,并对生成的迷宫图做一些说明。
![ff362eeba0299a424ff2418aa703cc8c.png](https://img-blog.csdnimg.cn/img_convert/ff362eeba0299a424ff2418aa703cc8c.png)
三、求解迷宫游戏
这里我们使用普通的搜索路径方法求解迷宫游戏,大概思路如下:从起点开始随机走,如果走不通了,则保存当前路径;然后逐步后退,直到能继续随机走;最终走完所有格点,则停止程序。 MATLAB代码如下:
function [map,dist]=maze_sove(map)
[a,b]=size(map);
model=map;
h=zeros(3);
h([2,4,6,8])=1;
t=0;
while 1
sample=conv2(model,h,'same');
sample(sample==1)=0;
sample([2,a*b-1])=1;
sample=sample>0;
model(sample~=model)=0;
if t==length(find(model>0))
break;
else
t=length(find(model>0));
end
end
map=model+map;
dist=length(find(map==2))-1;
后台回复
关键
词【
迷宫
】获得完整代码
到这里我们已经完成了迷宫游戏地图的生成、MATLAB自动求解所生成的迷宫游戏地图,一款豪华的私人定制迷宫游戏基本就完成了。
![7bded61e54e7ddf27db07ac77f7c125b.gif](https://img-blog.csdnimg.cn/img_convert/7bded61e54e7ddf27db07ac77f7c125b.gif)
四、手动求解迷宫游戏
话不多说,直接上代码。![6dbc45c19ba37803d18144b21516467e.png](https://img-blog.csdnimg.cn/img_convert/6dbc45c19ba37803d18144b21516467e.png)
function move(map)
clf;
map_draw(map, '迷宫游戏');
[e,f]=size(map);
curpos=[2,1];
H=text(curpos(2),curpos(1),'\bullet','HorizontalAlignment','Center','FontSize',45,'color','r');
tic;
while ~all(curpos == [e-1,f])
waitfor(gcf,'CurrentCharacter');
set(gcf,'CurrentCharacter','~');
switch double(key(1))
case 117
if map(max(curpos(1)-1,1),curpos(2))>0&&curpos(1)>1
set(H,'string',[]);
curpos(1)=curpos(1)-1;
H=text(curpos(2),curpos(1),'\bullet','HorizontalAlignment','Center','FontSize',45,'color','r');
end
case 100
if map(min(curpos(1)+1,e),curpos(2))>0&&curpos(1)
set(H,'string',[]);
curpos(1)=curpos(1)+1;
H=text(curpos(2),curpos(1),'\bullet','HorizontalAlignment','Center','FontSize',45,'color','r');
end
case 108
if map(curpos(1),max(curpos(2)-1,1))>0&&curpos(2)>1
set(H,'string',[]);
curpos(2)=curpos(2)-1;
H=text(curpos(2),curpos(1),'\bullet','HorizontalAlignment','Center','FontSize',45,'color','r');
end
case 114
if map(curpos(1),min(curpos(2)+1,f))>0&&curpos(2)
set(H,'string',[]);
curpos(2)=curpos(2)+1;
H=text(curpos(2),curpos(1),'\bullet','HorizontalAlignment','Center','FontSize',45,'color','r');
end
otherwise
end
end
time=toc;
str=num2str(['Your Last Time is: ' num2str(time) '秒']);
text(0.8*f,-1,str);
![8538942b871f56151f3ee04f741f1d0b.gif](https://img-blog.csdnimg.cn/img_convert/8538942b871f56151f3ee04f741f1d0b.gif)
五、迷宫游戏封装
通过前几部分,我们实现了实现了这款豪华私人订制版“迷宫游戏的”三大功能,即:随机生成迷宫地图、手动求解生成的迷宫、MATLAB自动求解生成的迷宫,下面我们将以上功能封装起来,完成这款迷宫游戏。function maze_main
global nar FIGURE;
close all;
clc;
nar=nargin;
if nar<1
a=input('请输入迷宫的行数:');
b=input('请输入迷宫的列数:');
a=2*a+1;
b=2*b+1;
map=maze(a,b);
str='迷宫游戏';
end
FIGURE=figure('KeyPressFcn',@move_spot);
map_draw(map,str);
num=3;
while num==3||num==1
num=input('请在以下操作中选择一项:\n1,运行迷宫游戏\n2,求解该迷宫\n3,重新选择迷宫\n4,退出\n');
switch num
case 1
figure(FIGURE);
move(map);
case 2
clf;
figure(FIGURE);
tic;
[map,~]=maze_sove(map);
map_draw(map,str);
case 3
maze_main;
case 4
return;
end
end
num=input('是否继续:\n1,继续\n2,退出\n');
switch num
case 1
maze_main;
case 2
return;
end
function move_spot(~,evnt)
assignin('caller','key',evnt.Key)
return
![717843ad11c54bdcea58b3cb5196c991.gif](https://img-blog.csdnimg.cn/img_convert/717843ad11c54bdcea58b3cb5196c991.gif)
![427fe4607f5807cf95eacdfcda6a022f.png](https://img-blog.csdnimg.cn/img_convert/427fe4607f5807cf95eacdfcda6a022f.png)
![f06b39bd64a057b10139fe37c8003ecf.png](https://img-blog.csdnimg.cn/img_convert/f06b39bd64a057b10139fe37c8003ecf.png)