迷宫游戏数据结构课程设计.docx
《迷宫游戏数据结构课程设计.docx》由会员分享,可在线阅读,更多相关《迷宫游戏数据结构课程设计.docx(21页珍藏版)》请在冰豆网上搜索。
迷宫游戏数据结构课程设计
计算机解迷宫问题通常用的是“穷举求解”方法,即从入口出发,顺着某一个方向进行探索,若能走通,则继续往前进;否则沿着原路退回,换一个方向继续探索,直至出口位置,求得一条通路。
假如所有可能的通路都探索到而未能到达出口,则所设定的迷宫没有通路。
迷宫的入口点的下标为(1,1),出口点的下标为(m,n)。
为处理方便起见,可在迷宫的四周加一圈障碍。
对于迷宫的任一位置,均可约定有东、南、西、北四个方向可通。
有一种简单走出迷宫的方法,把手放在右边的墙上开始前进,始终不要把手从墙上移开。
如果迷宫向右拐,你也顺着墙向右拐。
只要不把手从墙上移开,最终就会到达迷宫的出口。
当然这样得到的路径可能不是一个最短的路径,但它可以最终得到结果,换句话说,这种方法走不出迷宫的风险是最小的。
本设计是为了实现一个可视化迷宫,以及利用最短路径算法寻找迷宫的出路以及将最短路径打印在屏幕上,并且限制小老鼠不能穿越墙,只能在路径上移动。
而且可以根据自己的需要设计迷宫地图。
关键词迷宫;栈;VC++6.0
1课设题目
1.1课设题目
编写一个程序求解迷宫问题。
迷宫由m行n列的二维数组设置,0表示无障碍,1表示有障碍。
设入口为(1,1),出口为(m,n),每次只能从一个无障碍单元移到周围四个方向上任一无障碍单元。
编程实现对任意设定的迷宫,求出一条从入口到出口的通路,或得出没有通路的结论。
算法输入:
代表迷宫入口的坐标
算法输出:
穿过迷宫的结果。
算法要点:
创建迷宫,试探法查找路径,输出解
1.2基本要求:
1.求得的通路以三元组(i,j,d)的形式输出,其中:
(i,j)指示迷宫中的一个坐标,d表示走到下一个坐标的方向。
2.输出迷宫示意图
1.3需求分析
1、本程序实现迷宫的探索过程.以用户和计算机对话的方式,即在计算机终端上显示“提示信息”之后,由用户在键盘上输入演示程序中规定的运算命令,然后程序就探索路径并输出路径。
2、本演示程序中,输入形式以“回车符”为结束标志,且允许出现重复字符。
3、利用二维指针实现迷宫位置的存储,并用栈存贮探索路径,每个结点含三个整形变量。
输入的形式以回车结束。
4、本程序中,用户可以读去文件里的迷宫,也可自己重新输入迷宫,而且用户可以输入任意大小的迷宫,然后程序自动探索路径,并输出迷宫的路径。
2程序总体设计
2.1流程图:
1.功能结构图
2.画出主要数据结构的类图
class类名DataType//定义描述迷宫中当前位置的类型
数据成员
访问控制权限数据类型变量名;
public:
intx;//x代表当前位置的行坐标
inty;//y代表当前位置的列坐标
intdir;//dir表示移动到下一步的方向
class类名Move//定义下一个位置的方向
数据成员
访问控制权限数据类型变量名;
public:
intx;
inty;
class类名Node//结点
数据成员
访问控制权限数据类型变量名;
public:
DataTypedata;
Node*next;
class类名stack
数据成员
访问控制权限数据类型变量名;
private:
Node*top;//指向第一个结点的栈顶指针
成员函数
访问控制权限返回值类型函数名(参数列表)
public:
stack();//构造函数,置空栈
~stack();//析构函数
voidPush(DataTypedata);//把元素data压入栈中
DataTypePop();//使栈顶元素出栈
DataTypeGetPop();//取出栈顶元素
voidClear();//把栈清空
boolIsEmpty();//判断栈是否为空,如果为空则返回1,否则返回0
3.main函数流程图
2.探索路径函数findpath()
3.自行输入迷宫函数writefile()
2.2概要设计
1.①构建一个二维数组maze[M+2][N+2]用于存储迷宫矩阵
②自动或手动生成迷宫,即为二维数组maze[M+2][N+2]赋值
③构建一个队列用于存储迷宫路径
④建立迷宫节点structpoint,用于存储迷宫中每个节点的访问情况
⑤实现搜索算法
⑥屏幕上显示操作菜单
2.本程序包含10个函数:
(1)主函数main()
(2)手动生成迷宫函数shoudong_maze()
(3)打印迷宫路径(若存在路径)result_maze()
(4)入队enqueue()
(5)出队dequeue()
(6)判断队列是否为空is_empty()
(7)访问节点visit()
(8)搜索迷宫路径mgpath()
2.3运行结果及分析
总结
通过这段时间的数据结构课程设计,本人对计算机的应用,数据结构的作用以及C语言的使用都有了更深的了解。
尤其是C语言的进步让我深刻的感受到任何所学的知识都需要实践,没有实践就无法真正理解这些知识以及掌握它们,使其成为自己的财富。
在理论学习和上机实践的各个环节中,通过自主学习和认真听老师讲课分析,我收获了不少。
当然也遇到不少的问题,也正是因为这些问题引发的思考给我带了收获。
从当初不喜欢上机写程序到现在能主动写程序,从当初拿着程序不只如何下手到现在知道如何分析问题,如何用专业知识解决实际问题的转变,我发现无论是专业知识还是动手能力,自己都有很大程度的提高。
在这段时间里,我对for、while等的循环函数用法更加熟悉,逐渐形成了较好的编程习惯。
在老师的指导帮助下,同学们课余时间的讨论中,这些问题都一一得到了解决。
在程序的调试能力上,无形中得到了许多的提高。
例如:
头文件的使用,变量和数组的范围问题,定义变量时出现的问题等等。
在实际的上机操作过程中,不仅是让我们了解数据结构的理论知识,更重要的是培养解决实际问题的能力,所以相信通过此次实习可以提高我们分析设计能力和编程能力,为后续课程的学习及实践打下良好的基础。
时间过得真快,大学生活不知不觉就走过了一学期,这一学期的大学学习和课程实践阶段的提高,使我们本身知识得到提高的同时,也增强了我们对未来工作的信心,我们相信自己未来两年半的学习更使我们有能力胜任将来的工作。
源程序
#include
usingnamespacestd;
classT//定义描述迷宫中当前位置的结构类型
{
public:
intx;//x代表当前位置的行坐标
inty;//y代表当前位置的列坐标
intdir;//0:
无效,1:
东,2:
南,3:
西,4:
北
};
classLinkNode//链表结点
{
friendclassStack;
public:
Tdata;
LinkNode*next;
};
classStack
{
private:
LinkNode*top;//指向第一个结点的栈顶指针
public:
Stack();//构造函数,置空栈
~Stack()//析构函数
{}
voidPush(Te);//元素data入栈中
TPop();//栈顶元素出栈
TGetPop();//取出栈顶元素
voidClear();//把栈清空
boolempty();//判断栈是否为空,如果为空则返回1,否则返回0
};
Stack:
:
Stack()//构造函数,置空栈
{
top=NULL;
}
voidStack:
:
Push(Te)//元素x入栈中
{
LinkNode*P;
P=newLinkNode;
P->data=e;
P->next=top;
top=P;
}
TStack:
:
Pop()//栈顶元素出栈
{
TTemp;
LinkNode*P;
P=top;
top=top->next;
Temp=P->data;
deleteP;
returnTemp;
}
TStack:
:
GetPop()//取出栈顶元素
{
returntop->data;
}
voidStack:
:
Clear()//把栈清空
{
top=NULL;
}
boolStack:
:
empty()//判断栈是否为空,如果为空则返回1,否则返回0
{
if(top==NULL)return1;
elsereturn0;
}
intmove[4][2]={{0,1},{1,0},{0,-1},{-1,0}};//定义当前位置移动的4个方向
voidPrintPath(Stackp)//输出路径
{
cout<<"迷宫的路径为\n";
cout<<"括号内的内容分别表示为(行坐标,列坐标,数字化方向,方向)\n";
Stackt;//定义一个栈,按从入口到出口存取路径
inta,b;
Tdata;
LinkNode*temp;
temp=newLinkNode;//获取空间
temp->data=p.Pop();//取栈p的顶点元素,即第一个位置
t.Push(temp->data);//第一个位置入栈t
deletetemp;//释放空间
while(!
p.empty())//如果栈p非空,则反复转移
{
temp=newLinkNode;
temp->data=p.Pop();//获取下一个位置
//得到行走方向
a=t.GetPop().x-temp->data.x;//行坐标方向
b=t.GetPop().y-temp->data.y;//列坐标方向
if(a==1)temp->data.dir=1;//方向向下,用1表示
elseif(b==1)temp->data.dir=2;//方向向右,用2表示
elseif(a==-1)temp->data.dir=3;//方向向上,用3表示
elseif(b==-1)temp->data.dir=4;//方向向左,用4表示
t.Push(temp->data);//把新位置入栈
deletetemp;
}//输出路径,包括行坐标,列坐标,下一个位置方向
while(!
t.empty())//栈非空,继续输出
{
data=t.Pop();
cout<<'('<switch(data.dir)//输出相应的方向
{
case1:
cout<<"↓)\n";break;
case2:
cout<<"→)\n";break;
case3:
cout<<"↑)\n";break;
case4:
cout<<"←)\n";break;
case0:
cout<<")\n";break;
}
}
}
voidRestore(int**maze,intm,intn)//恢复迷宫
{
inti,j;
for(i=0;i