##大学数据结构课程设计报告题目:走迷宫游戏院(系):计算机工程学院学生姓名:班级:学号:起迄日期: 2011-6-21 至 2011-6-30指导教师:2010—2011年度第 2 学期一、需求分析1 问题描述走迷宫游戏程序开始运行时显示一个迷宫地图,迷宫中央有一只老鼠,迷宫的右下方有一个粮仓。
游戏的任务是使用键盘上的方向键操纵老鼠在规定的时间内走到粮仓处。
2 基本功能1) 老鼠形象可辨认,可用键盘操纵老鼠上下左右移动;2) 迷宫的墙足够结实,老鼠不能穿墙而过;3) 正确检测结果,若老鼠在规定时间内走到粮仓处,提示成功,否则提示失败;4) 添加编辑迷宫功能,可修改当前迷宫,修改内容:墙变路、路变墙;5) 找出走出迷宫的所有路径,以及最短路径。
利用序列化功能实现迷宫地图文件的存盘和读出等功能3 输入输出输入为字符型:1, 2, 3 分别实现功能选择w(上),s(下),a(左),d(右)控制迷宫的走向y表示确定 n表示否定二、 概要设计1. 设计思路:实现走迷宫game ()对迷宫地图进行修改change ()对修改的地图数组进行保存edit ()对修改的地图进行保存savemap ()实现自动搜路Mathpath ()对搜寻的路径进行输出print ()2.数据结构设计:采用的是栈来存储数据,进栈实际是在栈中插入三元组,出栈则只数组的个数进行操作抽象数据类型线性表的定义如下: ADT SqStack{数据对象:D={a i | a i ∈SElemType,i=1,2,3……,n,n ≥0} 数据关系:R1={<a i-1,a i >| a i-1,a i ∈D,i=1,2,3,……,n} 基本操作:SqStack *InitStack() 操作结果:创建一个空栈void Push(SqStack *S,SElemType data) 初始条件:栈S 已存在操作结果:插入一个元素,并且使数据个数加一(top++) void Pop(SqStack *S) 初始条件:栈S 已存在。
操作结果:栈中元素个数减一(top--) }2. 软件结构设计:game ()模块 函数原型:void game(int map1[h][w])//游戏函数 {#define killtime 15 clock_t start, finish; double duration;int x=1,y=1,m=0,n=0,M,N,MAP[100][100];//x->colom y->row char cCtrl='\0';cout<<" 游戏规则:"<<endl<<" w向上,s向下,a向左,d向右,q退出"<<endl<<" 按任意键开始,方向键开始计时"<<endl;for(M=0;M<=h-1;M++)for(N=0;N<=w-1;N++)MAP[M][N]=map1[M][N];{{start = clock();//开始计时while((cCtrl=getch())!='q'){switch(cCtrl){case 'w'://向上{ cout<<'\a';//响铃if(y>0&&!MAP[y-1][x])y--;}break;case 's'://下{ cout<<'\a';if(!MAP[y+1][x])y++;}break;case 'a'://左{ cout<<'\a';if(x>0&&!MAP[y][x-1])x--;}break;case 'd'://右{ cout<<'\a';if(!MAP[y][x+1])x++;}break;}system("cls");//刷屏for(m=0;m<h;m++){for(n=0;n<w;n++){if(m==y&&n==x){system("color 6");cout<<"◎";//现实老鼠所在位置}else{if(MAP[m][n])cout<<"■";//打印墙壁else{if(m==9&&n==8)cout<<"☆";//显示粮仓elsecout<<"□";//显示可行路径}}if(x==8&&y==9){finish = clock();//停止计时duration = (double)(finish - start) / CLOCKS_PER_SEC;//compute the timecout<<endl<<"你耗费的时间是:"<<endl<<duration<<"秒"<<endl;if(duration>killtime)//lose{cout<<" 你输了,完蛋了,小老鼠要饿死了囧rz!!"<<endl;}else//win{cout<<endl<<" └(^o^)┘小老鼠总算找到粮仓了,谢谢啊! "<<endl<<" 这是你赢得的金币◎,小老鼠奉上:"<<endl;cout<<" ";for(int i=0;i<20-duration;i++)cout<<"◎";cout<<endl;}exit(0);}}cout<<endl;}}}}}Mazepath()模块:void MazePath(int maze[][w],int x,int y)//找到全部路径的函数{int i;SElemType data;if(x==h-2&&y==w-2)//到达出口{print(S);return;}for(i=0;i<4;i++)//进行四个方向的判断{data.seat.r=x;data.seat.c=y;data.d=i;maze[x][y]=-1;x=x+move[i].r;//对下一个方向处理y=y+move[i].c;if(maze[x][y]==0)//如果下一方向可通,把此元素入栈{Push(S,data);MazePath(maze,x,y);//求下一元素为开始的路径Pop(S);}x=x-move[i].r;//若下一方向不通,回到此坐标y=y-move[i].c;maze[x][y]=0;}}三、详细设计1. 定义程序中所有用到的数据及其数据结构,及其基本操作的实现typedef struct{int r,c;}PosType;//坐标 r表示行,c表示列typedef struct{PosType seat;int d;}SElemType;//seat表示当前坐标,d表示当前要转的方向序号typedef struct{SElemType data[1000];int top;}SqStack;//栈元素类型,含有一个三元组,top表示该数组的元素个数SqStack *S;PosType move[4]={{0,1},{1,0},{0,-1},{-1,0}};//move 表示移动,分别是右、下、左、上int count=1;//用来统计路径条数2.主函数和其他函数的伪码算法void MazePath(int maze[][w],int x,int y)//找到全部路径的函数{int i;SElemType data;//定义三元组类型变量if(x==h-2&&y==w-2)//到达出口打印路径;for(i=0;i<4;i++)//进行四个方向的判断{把x,y赋给datadata.d=i;//方向记录maze[x][y]=-1;对下一个方向进行探索;if(maze[x][y]==0)//如果下一方向可通{把此元素入栈MazePath(maze,x,y);//求下一元素为开始的路径Pop(S);}若下一方向不通,返回到此坐标;maze[x][y]=0;}}void print(SqStack *s) //显示一条路径{//freopen("THEMAP.txt","a",stdout);int map[h][w]={//给出迷宫的矩阵}for(i=0;i<=s->top;i++){输出每一个坐标位置和探索的方向map[s->data[i].seat .r][s->data[i].seat.c]=2;//把坐标位置重新标记}count++;//路径记录加一输出字符模式的地图;}void game(int map1[h][w])//游戏函数{#define killtime 15clock_t start, finish;double duration;int x=1,y=1,m=0,n=0,M,N,MAP[100][100];//x->colom y->rowchar cCtrl='\0';初始化地图(赋值); {{start = clock();//开始计时while((cCtrl=getch())!='q'){switch(cCtrl){case 'w'://向上{ if(y>0&&!MAP[y-1][x])y--;}break;case 's'://下{ if(!MAP[y+1][x])y++;}break;case 'a'://左{ if(x>0&&!MAP[y][x-1])x--;}break;case 'd'://右{ if(!MAP[y][x+1])x++;}break;}system("cls");//刷屏打印出老鼠,墙壁,粮仓;if(x==8&&y==9){finish = clock();//停止计时duration = (double)(finish - start) / CLOCKS_PER_SEC;//compute the time 胜利和失败的处理;exit(0);}}cout<<endl;}}}}}void savemap(int map[h][w])//保存地图{以追加的方式打开一个文件;将地图以字符形式写入文件;将地图以数组形式写入文件;}void change(int map[h][w])//墙变路,路变墙{先以字符形式显示地图;输入你想改变的坐标;路变墙,墙变路;显示改变后的地图选择保存与否;继续游戏;}void edit(int game[]){int a[100000];FILE *fp;fp=fopen("ok.txt","r");//打开地图数组文件int t=0;while(fscanf(fp,"%d",&a[t])!=EOF)//没有到文件结尾{game[t]=a[t];//把读出的赋值到新的数组里面t=t+1;}fclose(fp);}3.主要函数的程序流程图开始计时输入w、s、a、d、qSif(!MAP[y+1][ x])y++;aif(x>0&&!MAP[y][x-1])x--;dif(!MAP[y][x+1])x++;q退出程序wif(y>0&&!MAP[y-1][x])y--;system("cls");打印墙壁和通路以及老鼠形象和粮仓形象void game(int map1[h][w])if(x==8&&y==9)停止计时游戏结束的处理void MazePath(int maze[][w],intx,int y)if(x==h-2&&y==w-2)到达出口yesnoprint(S);i表示方向if(i<4)data.seat.r=x;data.seat.c=y;data.d=i;maze[x][y]=-1;x=x+move[i].r;y=y+move[i].c;if(maze[x][y]==0)Push(S,data);Pop(S);X=x-move[i].r;y=y-move[i].c;maze[x][y]=0;4.函数之间的调用关系图。