数据结构课程设计走迷宫.docx
《数据结构课程设计走迷宫.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计走迷宫.docx(19页珍藏版)》请在冰豆网上搜索。
数据结构课程设计走迷宫
数据结构
课程设计报告
设计题目:
走迷宫游戏
专业:
计算机科技
院系:
计算机学院
姓名:
xxxxxxxx
学号:
xxxxxxxxx
时间:
2013年10月10日
目录
一、课程设计的目的………………………………………………………………..2
二、需求分析…………………………………………………………………………..2
三、课程设计报告内容…………………………………………………………..3
1.概要设计………………………………………………………………………………………..3
2.详细设计………………………………………….…………………………………………….4
3.调试分析…………………………………………………..……………………………………9
4.用户手册………………………………………………………………………………………..9
5.测试结果……………………………………………………………………………………..10
6.程序清单……………………………………………………………………………………..11
四、小结……………………………………………………16
五、参考文献…………………………………………16
一、课程设计的目的
(1)熟练使用C语言编写程序,解决实际问题;
(2)了解并掌握数据结构与算法的设计方法,具备初步的独立分析和设计能力;
(3)初步掌握软件开发过程的问题分析、系统设计、程序编码、测试等基本方法和技能;
(4)提高综合运用所学的理论知识和方法独立分析和解决问题的能力;
二、需求分析
程序开始运行时显示一个迷宫地图,迷宫中央有一只老鼠,迷宫的右下方有一个粮仓。
游戏的任务是使用键盘上的方向键操纵老鼠在规定的时间内走到粮仓处。
要求:
①老鼠形象可辨认,可用键盘操纵老鼠上下左右移动;
②迷宫的墙足够结实,老鼠不能穿墙而过;
③正确检测结果,若老鼠在规定时间内走到粮仓处,提示成功,否则提示失败;
④添加编辑迷宫功能,可修改当前迷宫,修改内容:
墙变路、路变墙;
⑤找出走出迷宫的所有路径,以及最短路径。
利用序列化功能实现迷宫地图文件的存盘和读出等功能
三、实验报告内容
1概要设计
(1)具体要求
①构建一个二维数组maze[M+2][N+2]用于存储迷宫矩阵
②自动或手动生成迷宫,即为二维数组maze[M+2][N+2]赋值
③构建一个队列用于存储迷宫路径
④建立迷宫节点structpoint,用于存储迷宫中每个节点的访问情况
⑤实现搜索算法⑥屏幕上显示操作菜单
(2)本程序包含10个函数:
主函数main()
手动生成迷宫函数shoudong_maze()
自动生成迷宫函数zidong_maze()
将迷宫打印成图形print_maze()
打印迷宫路径(若存在路径)result_maze()
入队enqueue()
出队dequeue()
判断队列是否为空is_empty()
访问节点visit()
搜索迷宫路径mgpath()
2详细设计
实现概要设计中定义的所有数据类型及操作的伪代码算法
节点类型和指针类型
迷宫矩阵类型:
intmaze[M+2][N+2];为方便操作使其为全局变量
迷宫中节点类型及队列类型:
structpoint{introw,col,predecessor}que[512]
迷宫的操作
(1)手动生成迷宫
voidshoudong_maze(intm,intn)
{定义i,j为循环变量
for(i<=m)
for(j<=n)
输入maze[i][j]的值
}
(2)自动生成迷宫
voidzidong_maze(intm,intn)
{定义i,j为循环变量
for(i<=m)
for(j<=n)
maze[i][j]=rand()%2//由于rand()产生的随机数是从0到RAND_MAX,RAND_MAX是定义在stdlib.h中的,其值至少为32767),要产生从X到Y的数,只需要这样写:
k=rand()%(Y-X+1)+X;
}
(3)打印迷宫图形
voidprint_maze(intm,intn)
{用i,j循环变量,将maze[i][j]输出□、■}
(4)打印迷宫路径
voidresult_maze(intm,intn)
{用i,j循环变量,将maze[i][j]输出□、■、☆}
搜索迷宫路径
①迷宫中队列入队操作
voidenqueue(structpointp)
{将p放入队尾,tail++}
②迷宫中队列出队操作
structpointdequeue(structpointp)
{head++,返回que[head-1]}
③判断队列是否为空
intis_empty()
{返回head==tail的值,当队列为空时,返回0}
④访问迷宫矩阵中节点
voidvisit(introw,intcol,intmaze[41][41])
{建立新的队列节点visit_point,将其值分别赋为row,col,head-1,maze[row][col]=2,表示该节点以被访问过;调用enqueue(visit_point),将该节点入队}
⑤路径求解
voidmgpath(intmaze[41][41],intm,intn)
{先定义入口节点为structpointp={0,0,-1},从maze[0][0]开始访问。
如果入口处即为障碍,则此迷宫无解,返回0,程序结束。
否则访问入口节点,将入口节点标记为访问过maze[p.row][p.col]=2,调用函数enqueue(p)将该节点入队。
判断队列是否为空,当队列不为空时,则运行以下操作:
{调用dequeue()函数,将队头元素返回给p,
如果p.row==m-1且p.col==n-1,即到达出口节点,即找到了路径,结束
如果p.col+1如果p.row+1如果p.col-1>0且maze[p.row][p.col-1]==0,说明未到迷宫左边界,且其左方有通路,则visit(p.row,p.col-1,maze),将左方节点入队标记已访问
如果p.row-1>0且maze[p.row-1][p.col]==0,说明未到迷宫上边界,且其上方有通路,则visit(p.row,p.col+1,maze),将上方节点入队标记已访问
}
访问到出口(找到路径)即p.row==m-1且p.col==n-1,则逆序将路径标记为3即maze[p.row][p.col]==3;
while(p.predecessor!
=-1)
{p=queue[p.predecessor];maze[p.row][p.col]==3;}
最后将路径图形打印出来。
菜单选择
while(cycle!
=(-1))
{
printf("╔═══════════════════════════╗\n");
printf("║欢迎进入走迷宫游戏演示系统║\n");
printf("║----------------------------------------------║\n");
printf("║-1.手动生成迷宫║\n");
printf("║-2.系统自动生成迷宫║\n");
printf("║-3.退出系统║\n");
printf("╚═══════════════════════════╝\n");
printf(">>>>>>>\n");
printf("请选择你的操作[]\b\b");
scanf("%d",&i);
switch(i)
{
case1:
printf("\n请输入行数[]\b\b");scanf("%d",&m);
printf("\n");
printf("请输入列数[]\b\b");scanf("%d",&n);
while((m<=0||m>39)||(n<=0||n>39))
{
printf("\n抱歉,你输入的行列数超出预设范围(0-39,0-39),请重新输入:
\n\n");
printf("请输入行数[]\b\b");scanf("%d",&m);
printf("\n");
printf("请输入列数[]\b\b");scanf("%d",&n);
}
shoudong_maze(m,n);
print_maze(m,n);
mgpath(maze,m,n);
if(X!
=0)
result_maze(m,n);
printf("\n\nPressEnterContiue!
\n");
getchar();
while(getchar()!
='\n');break;
case2:
printf("\n请输入行数[]\b\b");scanf("%d",&m);
printf("\n");
printf("请输入列数[]\b\b");scanf("%d",&n);
while((m<=0||m>39)||(n<=0||n>39))
{
printf("\n抱歉,你输入的行列数超出预设范围(0-39,0-39),请重新输入!
\n\n");
printf("请输入行数[]\b\b");scanf("%d",&m);
printf("\n");
printf("请输入列数[]\b\b");scanf("%d",&n);
}
zidong_maze(m,n);
print_maze(m,n);
mgpath(maze,m,n);
if(X!
=0)result_maze(m,n);
printf("\n\nPressEnterContiue!
\n");
getchar();
while(getchar()!
='\n');break;
case3:
cycle=(-1);break;
default:
printf("\n");printf("你的输入有误!
\n");
printf("\nPressEnterContiue!
\n");getchar();while(getchar()!
='\n');break;
}
}
注:
具体源代码见附录
3.调试分析
在调试过程中,首先使用的是栈进行存储,但是产生的路径是多条或不是最短路径,所以通过算法比较,改用此算法
4.用户手册
本程序的运行环境为windows764位操作系统
进入演示程序后即显示文本方式的用户界面
5.测试结果
图1手动生成迷宫
图2系统自动生成迷宫
6.程序清单
#include
#include
#defineN39
#defineM39
intX;
intmaze[N+2][M+2];
structpoint{
introw,col,predecessor;
}queue[512];
inthead=0,tail=0;
voidshoudong_maze(intm,intn){
inti,j;
printf("\n\n");
printf("请按行输入迷宫,0表示通路,1表示障碍:
\n\n");
for(i=0;ifor(j=0;jscanf("%d",&maze[i][j]);
}
voidzidong_maze(intm,intn){
inti,j;
printf("\n迷宫生成中……\n\n");
system("pause");
for(i=0;ifor(j=0;jmaze[i][j]=rand()%2;
//由于rand()产生的随机数是从0到RAND_MAX
//RAND_MAX是定义在stdlib.h中的,其值至少为32767)
//要产生从X到Y的数,只需要这样写:
k=rand()%(Y-X+1)+X;
}
voidprint_maze(intm,intn){
inti,j;
printf("\n迷宫生成结果如下:
\n\n");
printf("迷宫入口\n");
printf("↓");
for(i=0;i{
printf("\n");
for(j=0;j{
if(maze[i][j]==0)printf("□");
if(maze[i][j]==1)printf("■");}
}
printf("→迷宫出口\n");
}
voidresult_maze(intm,intn){
inti,j;
printf("迷宫通路(用'鼠'表示)如下所示:
\n\t");
for(i=0;i{
printf("\n");
for(j=0;jif(maze[i][j]==0||maze[i][j]==2)printf("□");
if(maze[i][j]==1)printf("■");
if(maze[i][j]==3)printf("鼠");
}
}
}
voidenqueue(structpointp){
queue[tail]=p;
tail++;
}
structpointdequeue(){
head++;
returnqueue[head-1];
}
intis_empty(){
returnhead==tail;
}
voidvisit(introw,intcol,intmaze[41][41]){
structpointvisit_point={row,col,head-1};
maze[row][col]=2;
enqueue(visit_point);
}
intmgpath(intmaze[41][41],intm,intn){
X=1;
structpointp={0,0,-1};
if(maze[p.row][p.col]==1){
printf("\n--------------------------------------------------\n");
printf("此迷宫无解\n\n");
X=0;
return0;
}
maze[p.row][p.col]=2;
enqueue(p);
while(!
is_empty())
{
p=dequeue();
if((p.row==m-1)&&(p.col==n-1))break;
if((p.col+1if((p.row+1if((p.col-1>=0)&&(maze[p.row][p.col-1]==0))visit(p.row,p.col-1,maze);
if((p.row-1>=0)&&(maze[p.row-1][p.col]==0))visit(p.row-1,p.col,maze);
}
if(p.row==m-1&&p.col==n-1){
printf("\n--------------------------------------------------\n");
printf("迷宫路径为:
\n");
printf("(%d,%d)\n",p.row,p.col);
maze[p.row][p.col]=3;
while(p.predecessor!
=-1){
p=queue[p.predecessor];
printf("(%d,%d)\n",p.row,p.col);
maze[p.row][p.col]=3;
}
}
else{
printf("\n--------------------------------------------------\n");
printf("此迷宫无解!
\n\n");
X=0;
}
return0;
}
intmain()
{
inti,m,n,cycle=0;
system("cls");
system("color1f");
printf("┏━━━━━━━━━━━━━━━━━━━━━━━━━┓\n");
printf("┃㊣必做题:
走迷宫游戏㊣┃\n");
printf("┃姓名:
xxxx┃\n");
printf("┃学号:
xxxxxxxxx┃\n");
printf("┗━━━━━━━━━━━━━━━━━━━━━━━━━┛\n");
while(cycle!
=(-1))
{
printf("╔══════════════════════════════════╗\n");
printf("║欢迎进入走迷宫游戏演示系统║\n");
printf("║-------------------------------------------║\n");
printf("║1.手动生成迷宫║\n");
printf("║2.系统自动生成迷宫║\n");
printf("║3.退出系统║\n");
printf("╚══════════════════════════════════╝\n");
printf(">>>>>>>\n");
printf("请选择你的操作[]\b\b");
scanf("%d",&i);
switch(i)
{
case1:
printf("\n请输入行数[]\b\b");scanf("%d",&m);
printf("\n");
printf("请输入列数[]\b\b");scanf("%d",&n);
while((m<=0||m>39)||(n<=0||n>39))
{
printf("\n抱歉,你输入的行列数超出预设范围(0-39,0-39),请重新输入:
\n\n");
printf("请输入行数[]\b\b");scanf("%d",&m);
printf("\n");
printf("请输入列数[]\b\b");scanf("%d",&n);
}
shoudong_maze(m,n);
print_maze(m,n);
mgpath(maze,m,n);
if(X!
=0)
result_maze(m,n);
printf("\n\nPressEnterContiue!
\n");
getchar();
while(getchar()!
='\n');break;
case2:
printf("\n请输入行数[]\b\b");scanf("%d",&m);
printf("\n");
printf("请输入列数[]\b\b");scanf("%d",&n);
while((m<=0||m>39)||(n<=0||n>39))
{
printf("\n抱歉,你输入的行列数超出预设范围(0-39,0-39),请重新输入!
\n\n");
printf("请输入行数[]\b\b");scanf("%d",&m);
printf("\n");
printf("请输入列数[]\b\b");scanf("%d",&n);
}
zidong_maze(m,n);
print_maze(m,n);
mgpath(maze,m,n);
if(X!
=0)result_maze(m,n);
printf("\n\nPressEnterContiue!
\n");
getchar();
while(getchar()!
='\n');break;
case3:
cycle=(-1);break;
default:
printf("\n");printf("你的输入有误!
\n");
printf("\nPressEnterContiue!
\n");getchar();while(getchar()!
='\n');break;
}
}
}
四、小结
通过这段时间的课程设计,我对计算机的应用,数据结构的作用以及C语言的使用都有了更深的了解。
尤其是C语言的进步让我深刻的感受到任何所学的知识都需要实践,没有实践就无法真正理解这些知识以及掌握它们,使其成为自己的财富。
在理论学习和上机实践的各个环节中,通过自主学习和请教老师,我收获了不少。
当然也遇到不少的问题,也正是因为这些问题引发的思考给我带了收获。
从当初不喜欢上机写程序到现在能主动写程序,从当初拿着程序不只如何下手到现在知道如何分析问题,如何用专业知识解决实际问题的转变,我发现无论是专业知识还是动手能力,自己都有很大程度的提高。
在这段时间里,我对for、while等的循环函数用法更加熟悉,逐渐形成了较好的编程习惯。
在老师的指导帮助下,同学们课余时间的讨论中,这些问题都一一得到了解决。
在程序的调试能力上,无形中得到了许多的提高。
五、参考文献
1严蔚敏,吴伟民编著.数据结构(C语言版)--北京:
清华大学出版社,
2严蔚敏,吴伟民米宁编著.数据结构题集(C语言版)--北京:
清华大学出版社,