数据结构迷宫求解课程设计报告.docx
《数据结构迷宫求解课程设计报告.docx》由会员分享,可在线阅读,更多相关《数据结构迷宫求解课程设计报告.docx(18页珍藏版)》请在冰豆网上搜索。
![数据结构迷宫求解课程设计报告.docx](https://file1.bdocx.com/fileroot1/2022-11/24/5c4a29f1-aa16-479a-bf71-9e56494ebba1/5c4a29f1-aa16-479a-bf71-9e56494ebba11.gif)
数据结构迷宫求解课程设计报告
课程设计报告
课程名称:
数据结构
报告题目:
迷宫求解
学生姓名:
XX
所在学院:
信息科学与工程
专业班级:
软件工程
学生学号:
XXXXXXXXXXX
指导教师:
XXX
2017年12月29日
课程设计任务书
报告题目
迷宫求解程序设计
完成时间
2017.12.29
学生姓名
专业
班级
指导教师
XXX
职称
总体设计要求和技术要点
课程设计要求
1.可以输入一个任意大小的迷宫数据,用非递归的方法求出一条走出迷宫的路径,并将路径输出;
2.在上交资料中请写明:
存储结构、基本算法(可以使用程序流程图)、源程序、测试数据和结果、算法的时间复杂度、另外可以提出算法的改进方法;
工作内容及时间进度安排
第17周:
周1---周3:
立题、论证方案设计
周4---周5:
完成项目一,项目二的整体设计
第18周:
周1---周2:
调试程序,解决问题
周3---周5:
写实验报告
课程设计成果
1.程序设计内容以及对应的软件程序
2.课程设计总结报告
摘要
本程序主要是求迷宫中从人口到出口的所有路径是一个经典的程序设计问题。
计算机解迷宫时,通常用的是“穷举求解”的方法,即从入口出发,顺某一方向向前探索,若能走通,则继续往前走;否则沿原路返回,换一个方向在继续探索,直至所有可能的通路都探索完为止。
当前位置“可通”,则纳入“当前路径”,并继续朝“下一位置”探索,即切换为“下一位置”为“当前位置”,如此重复直至到达出口;若当前位置“不可通”,则应顺着“来的方向”退回到“前一通道块”,若该通道块的四周4个方块均“不可通”则应从当前路径删除该通道块。
所谓“下一位置”指的是“当前位置”四周4个方向(东、南、西、北)上相邻的方块。
以栈S来记录“当前路径”,则栈顶中存放的是“当前路径上最后一个通道块”。
所以即为“当前路径入栈”;“从当前路径上删除前一通道块”为“出栈”。
在这个过程中可以输出迷宫所走通的路径,在这次课程设计中迷宫是由数组预先定义好的,不能由用户定义生成,可以加入随机函数,自动生成二维数组,还可以用户自己输入迷宫。
关键词:
栈;存储结构;数组
一、课题分析
(1)该题目为迷宫求解。
(2)此课题是对迷宫问题的求解。
包括用数组生成迷宫,显示输出路径因此,本程序设计共需设计一个主程序以及若干个子程序。
(3)在本课程设计程序里,主程序主要是以一个m×n的长方形表示迷宫,0和1分别表示迷宫中的通路和障碍。
设计一个程序,对设定的迷宫,求出一条从入口到出口的通路,子程序实现迷宫地图的查看和通过迷宫后的路径查询。
二、需求分析
1.主模块功能描述
显示提示语句提示用用户选择输入执行的功能。
(1)开始迷宫求解游戏
(2)查询迷宫地图
(3)查询通过迷宫后的路径
2.子程序模块设计
(1)迷宫求解游戏
输入1开始游戏
(2)查询迷宫地图
在菜单中输入2查看迷宫求解的地图
(3)查询通过迷宫后的路径
输入2查询通关路径
三、设计方案
1.类设计
构建一个Hidding类,并有私有成员:
x坐标,y坐标,位置标志,初始方向;共有成员:
PrintMap打印地图,GameFunction游戏主循环,Move_up向上移动,Move_down向下移动,Move_left向左移动,Move_right向右移动,IsGameOver判断游戏是否结束,Move_Keys接收移动的指令,InDirection相反方向输出,dir_flage方向标志,Hidding:
:
Start()开始游戏等等类,在通过类的实现来执行相应的功能,具体代码如下:
classHidding
{
private:
intpoint_x;//控制运动的点的x坐标
intpoint_y;//控制运动的点的y坐标
intflage;//判断标志
intdirection;//初始方向
public:
Hidding();
intPrintMap(intmap[H][H]);//打印地图
intGameFunction(intmap[H][H],SqStack&S);//游戏主循环
intMove_up(intmap[H][H],SqStack&S);//向上移动
intMove_down(intmap[H][H],SqStack&S);//向下移动
intMove_left(intmap[H][H],SqStack&S);//向左移动
intMove_right(intmap[H][H],SqStack&S);//向右移动
boolIsGameOver(intmap[H][H]);//判断游戏是否结束
intMove_Keys(intkey,intmap[H][H],SqStack&S);//接收移动的指令
intInDirection(intkey);//相反方向输出
intdir_flage;//方向标志
intOut(intmap[H][H]);//显示通关路径
intOuta(intmap[H][H]);
intHidding:
:
menu();//菜单
intHidding:
:
Start();//开始游戏
};
2.程序模块设计
设计方案与实施与总体设计思想
(1)迷宫形状由0表示可通过,用1表示障碍。
为方便用0,1输入,2表示起点,3表示终点。
并把迷宫图形保存在二维数组Map中,而打印出的图形中“□”表示能通过,“■”表示障碍。
对探索过的位置加以标记“☆”,起点和终点分别由“⊙”,“◎”表示,“★”表示为当前目标位置。
(2)根据二位字符数组和加标记的位置坐标,输出迷宫的图形。
(3)该程序在获取迷宫图形结构后,目标点从起点开始搜索可通过的路径,目标点通过判断身边上下左右四个位置是否有障碍而选择前进路径,如果判断之后遇到没有可以通过的方向,将会退回之前的位置,另行判断。
直至目标点找到出口后,输出通过的路径,程序结束。
1.2程序设计流程图
入口出发,顺某一方向向前探索,若能走通,则继续往前走;否则沿原路返回,换一个方向在继续探索,直至所有可能的通路都探索完为止。
图1—游戏的主循环
3.主模块
若当前位置“可通”,则纳入“当前路径”,并继续朝“下一位置”探索,即切换为“下一位置”为“当前位置”,如此重复直至到达出口;若当前位置“不可通”,则应顺着“来的方向”退回到“前一通道块”,然后朝着除“来向”之外的其他方向继续探索;若该通道块的四周4个方块均“不可通”则应从当前路径删除该通道块。
所谓“下一位置”指的是“当前位置”四周4个方向(东、南、西、北)上相邻的方块。
以栈S来记录“当前路径”,则栈顶中存放的是“当前路径上最后一个通道块”。
所以即为“当前路径入栈”;“从当前路径上删除前一通道块”为“出栈”。
图2—游戏的主框架
3.1子模块
图3—实现迷宫游戏地图查询后开始游戏
3.程序调试结果及分析
3.1主菜单
这是主界面,提示A、B、C各自代表的功能,输入1或2或3会跳转到相应的功能模块,输入1开始游戏,输入2可查看需要通关的游戏地图,输入3返回。
图4—程序界面图
3.2功能A模块
当从键盘输入1进入A功能模块,此图是寻找迷宫路径,游戏会由电脑自动完成,入口出发,顺某一方向向前探索,若能走通,则继续往前走;否则沿原路返回,换一个方向在继续探索,直至所有可能的通路都探索完为止,若是成功找到路径,则输出恭喜过关,并且提示是否查看通关路径。
图5—程序正在运行图
3.3功能B模块
从键盘输入2查询迷宫地图,可显示游戏需要通关的迷宫地图,继续输入1可以开始游戏。
图6—迷宫地图
3.4功能C模块
游戏的主循环的类的实现表示游戏的开始,判断当前位置标记是否为3,如果为3,则表示该位置为终点,游戏结束,输出恭喜过关,提示是否查看通关路径,从键盘输入2查询通关路径
图7—目标完成游戏路径图
图
四、详细设计
1.用结构体构建栈
通过构建的栈实现迷宫求解时寻找路径的数据的存放于取出,其关键代码如下:
typedefstruct
{
SElemType*top;//顶部指针
SElemType*base;//底部指针
intstacksize;//当前栈的大小
}SqStack;
2.构建类
构建一个Hidding类,并有私有成员:
x坐标,y坐标,位置标志,初始方向;共有成员:
PrintMap打印地图,GameFunction游戏主循环,Move_up向上移动,Move_down向下移动,Move_left向左移动,Move_right向右移动,IsGameOver判断游戏是否结束,Move_Keys接收移动的指令,InDirection相反方向输出,dir_flage方向标志,Hidding:
:
Start()开始游戏等等类,在通过类的实现来执行相应的功能,具体代码如下:
classHidding
{
private:
intpoint_x;//控制运动的点的x坐标
intpoint_y;//控制运动的点的y坐标
intflage;//判断标志
intdirection;//初始方向
public:
Hidding();
intPrintMap(intmap[H][H]);//打印地图
intGameFunction(intmap[H][H],SqStack&S);//游戏主循环
intMove_up(intmap[H][H],SqStack&S);//向上移动
intMove_down(intmap[H][H],SqStack&S);//向下移动
intMove_left(intmap[H][H],SqStack&S);//向左移动
intMove_right(intmap[H][H],SqStack&S);//向右移动
boolIsGameOver(intmap[H][H]);//判断游戏是否结束
intMove_Keys(intkey,intmap[H][H],SqStack&S);//接收移动的指令
intInDirection(intkey);//相反方向输出
intdir_flage;//方向标志
intOut(intmap[H][H]);//显示通关路径
intOuta(intmap[H][H]);
intHidding:
:
menu();//菜单
intHidding:
:
Start();//开始游戏
};
3.用数组构建一个迷宫
1.迷宫形状由0表示可通过,用1表示障碍。
为方便用0,1输入,2表示起点,3表示终点。
并把迷宫图形保存在二维数组Map中,而打印出的图形中“□”表示能通过,“■”表示障碍。
对探索过的位置加以标记“☆”,起点和终点分别由“⊙”,“◎”表示,“★”表示为当前目标位置,其关键代码如下:
intmap[H][H]=
{
1,1,1,1,1,1,1,1,1,1,//(9,0)(9,9)
1,0,0,0,0,0,1,0,0,1,
1,0,1,1,0,0,1,0,0,1,
1,0,0,1,1,0,1,0,1,1,
1,1,0,0,1,0,0,0,1,1,
1,1,0,1,1,1,1,0,0,1,
1,1,0,1,1,1,1,1,0,1,
1,0,0,1,1,1,1,1,0,1,
1,2,1,1,1,1,1,1,3,1,
1,1,1,1,1,1,1,1,1,1//(0,0)(0,9)
};
2.打印出的图形中“□”表示能通过,“■”表示障碍。
对探索过的位置加以标记“☆”,起点和终点分别由“⊙”,“◎”表示,“★”表示为当前目标位置,其关键代码如下:
intHidding:
:
PrintMap(intmap[H][H])
{
for(inti=0;i{
for(intj=0;j{
switch(map[i][j])
{
case0:
cout<<"□";
break;
case1:
//墙
cout<<"■";
break;
case2:
//起点
cout<<"⊙";
break;
case3:
//终点
cout<<"◎";
break;
case7:
//走过的路径
cout<<"☆";
break;
case9:
cout<<"★";
break;
default:
break;
}
}
cout<}
return0;
}//PrintMap
4.游戏移动控制指令
构建一个栈,用Key控制移动,上移指令Key=8,下移指令Key=5,左移指令Key=4,右移指令Key=6,其关键代码如下:
intHidding:
:
Move_Keys(intkey,intmap[H][H],SqStack&S)
{
switch(key)
{
case8:
Move_up(map,S);
break;
case4:
Move_left(map,S);
break;
case6:
Move_right(map,S);
break;
case5:
Move_down(map,S);
break;
default:
break;
}
return0;
}//Move_Keys
5.游戏移动控制指令四个方向的实现
以向上移动指令的实现为例,判断是否是走过的路径,若是则x-1当前位置标记为0;判断前方是否可行,若是x-1,当前位置标记为7,(7为走过的路径),并且入栈执行一次;若前方数组值为1,表示不能通过,继续判断其他方向是否可以通过,如map[point_x][point_y-1]==0则表示左侧可以通过,direction=4,移动方向为左,入栈一次,其他方向的移动指令大致相同,都是先判断,在通过入栈实现移动游戏移动过程中若是未找到通路,需要返回,则执行InDirection反方向移动指令。
其关键代码如下:
intHidding:
:
Move_up(intmap[H][H],SqStack&S)
{
if(map[point_x-1][point_y]==7)
{
map[point_x][point_y]=0;
point_x-=1;
}
elseif((map[point_x-1][point_y]==0&&direction!
=5)||map[point_x-1][point_y]==3)//如果前方可行
{
map[point_x][point_y]=7;
point_x-=1;
Push(S,direction);
}
if(map[point_x-1][point_y]==1)
{
if(map[point_x][point_y-1]==0)
{
direction=4;
Push(S,direction);
}
elseif(map[point_x][point_y+1]==0)
{
direction=6;
Push(S,direction);
}
else
{
dir_flage=Pop(S);
InDirection(dir_flage);
map[point_x][point_y]=0;
}
}
return0;
}//Move_up
6.游戏移动过程中若是未找到通路,需要返回的指令
判断上一步执行的指令Key,在执行放方向移动的指令,具体代码如下:
intHidding:
:
InDirection(intkey)
{
switch(key)
{
case8:
direction=5;
break;
case4:
direction=6;
break;
case5:
direction=8;
break;
case6:
direction=4;
break;
default:
break;
}
return0;
}//InDirection
7.游戏的主循环
用一个sleep函数控制游戏的速度,具体代码如下:
intHidding:
:
GameFunction(intmap[H][H],SqStack&S)
{
Sleep(100);
PrintMap(map);
system("cls");
while(!
IsGameOver(map))
{
map[point_x][point_y]=9;
PrintMap(map);
Move_Keys(direction,map,S);
cout<<"方向:
";
switch(direction)
{
case8:
cout<<"上"<break;
case5:
cout<<"下";
break;
case6:
cout<<"右";
break;
case4:
cout<<"左";
break;
}
cout<system("cls");
Sleep(100);
}
return0;
}//GameFunction
8.游戏的开始于结束
游戏的主循环的类的实现表示游戏的开始,判断当前位置标记是否为3,如果为3,则表示该位置为终点,游戏结束,输出恭喜过关,提示是否查看通关路径,具体代码如下:
intHidding:
:
Start()
{
hid.GameFunction(map,S1);
if(hid.IsGameOver(map)
cout<<"恭喜过关!
"<cout<<"输入2显示通关路径。
"<}
boolHidding:
:
IsGameOver(intmap[H][H])
{
if(map[point_x][point_y]==3)//3表示终点
returntrue;
else
returnfalse;
}//IsGameOver
9.迷宫地图的查看与通关后的路径查询
开始游戏前可以查看迷宫的地图,在开始游戏寻找到通关路径后可以查看对应的路径,用for循环实现二维数组的读出,相应的通关路径会以☆符合标记出来,具体代码如下:
for(inti=1;i<=H;i++)
for(intj=1;j<=H;j++)
if(map[i][j]=0)
cout<