完整版C++毕业课程设计自动走迷宫小游戏.docx
- 文档编号:8123581
- 上传时间:2023-01-28
- 格式:DOCX
- 页数:18
- 大小:195.81KB
完整版C++毕业课程设计自动走迷宫小游戏.docx
《完整版C++毕业课程设计自动走迷宫小游戏.docx》由会员分享,可在线阅读,更多相关《完整版C++毕业课程设计自动走迷宫小游戏.docx(18页珍藏版)》请在冰豆网上搜索。
完整版C++毕业课程设计自动走迷宫小游戏
自动走迷宫小游戏
第一章课程设计目的和要求
1.1课程设计的目的
根据课堂讲授内容,做相应的自主练习,消化课堂所讲解的内容;通过调试典型例题或习题积累调试C++程序的经验;通过完成辅导教材中的编程题,逐渐培养学生的编程能力、用计算机解决实际问题的能力。
同时在设计的过程中发现自己的不足之处,对以前所学过的知识理解的更加深刻,掌握得更加牢固。
1.2课程设计的要求
迷宫生成。
迷宫有起点和终点,生成的迷宫需要满足从起点到终点有通路,不需要唯一;
尝试走迷宫。
迷宫中每个位置有8个方向,每个方向都有可能有障碍。
从起点出发,行进过程中遇到岔路口需要记录,选择一条路继续,如果此路不通,能够回溯到刚才的岔路口继续,直到走到终点;
记录走迷宫成功的路线到文本文件。
第二章课程设计任务内容
选择手动或者自动生成一个n×m的迷宫,将迷宫的左上角作入口,右下角作出口,设“0”为通路,“1”为墙,即无法穿越。
假设从起点出发,目的为右下角终点,可向“上、下、左、右、左上、左下、右上、右下”8个方向行走。
如果迷宫可以走通,则用“■”代表“1”,用“□”代表“0”,用“☆”代表行走迷宫的路径。
输出迷宫原型图、迷宫路线图以及迷宫行走路径。
如果迷宫为死迷宫,则只输出迷宫原型图。
第三章详细设计说明
3.1模块描述
整个实验将实现迷宫路径的查找,并图形化输出其中最短的路径,迷宫使用二维数组存放。
机器通过穷举法解出迷宫的路径,最后输出。
整个实验分为以下几个模块:
创建模块。
本实验的创建包含两方面,迷宫的定义和脚步的初始化。
迷宫的定义通过修改二维数组实现,最终创建一个确定的迷宫。
脚步的初始化由程序自行完成.
路径查找模块。
路径查找核心分为两个部分:
路径查找、更优解替换。
路径查找包括可通性检查、脚步前进、脚步后退三个模块。
可通性检查会检查当前脚步的四个方向是否有通路。
脚步前进可以在有通路的情况下抵达下一个点,并记录在脚步双向链表中。
脚步后退使在当前脚步无路的情况下后退一步,并转向其他方向,同时删除最后一个脚步。
可通性检查。
可通性检查用来判断指定的方向是否可以通过。
需要判断两方面内容,即下一点是否有障碍和下一点是否已包含在了已有路径之中。
若同时满足无障碍和无包含条件,则可以通过。
否则不能通过。
脚步前进。
下一点若经过检查可以通过,则通过move()函数完成前进。
“前进”的实现有两方面,第一方面,将新脚步纳入双向链表中,另一方面,在迷宫数组中将本步坐标所指标记为“已走”。
脚步后退。
若本步四个方向都不能行走,则通过back()函数退后。
退后包括两方面,一方面把链表中最后一个节点抛弃,当前脚步指向倒数第二个节点。
另一方面,将迷宫数组中已抛弃节点指向的元素重新标记为“未走”,以便进行其他路径的寻路操作时可以顺利通过。
输出模块。
实现迷宫解的图形化显示。
其他模块。
格式化模块,用于迷宫求解后的处理。
迷宫数组改写模块,按照求解的结果改写迷宫二维数组,以满足最终输出需要。
功能模块图如下图所示
图3—1功能模块图
3.2函数说明
1.data()
函数原型voiddata(intm,intn)
data()函数用于当用户输入的不是规整的m行n列的迷宫,用来生成规则的数字迷宫
2.print_maze()
函数原型voidprint_maze(intm,intn)
print_maze()函数用于打印迷宫外壳
3.result_maze()
函数原型voidresult_maze(intm,intn)
result_maze()函数用于打印输出迷宫的星号路径
4.visit()
函数原型voidvisit(introw,intcol,intmaze[51][51])
visit()函数用于访问迷宫矩阵中的节点
5.)
)这个是打印输出迷宫的星号路径
{
inti,j;
cout<<"迷宫通路(用☆表示)如下所示:
\n\t";
for(i=0;i { cout<<"\n"; for(j=0;j { if(maze[i][j]==0||maze[i][j]==2)2是队列中访问过的点 cout<<"□"; if(maze[i][j]==1) cout<<"■"; if(maze[i][j]==3)3是标记的可以走通的路径 cout<<"☆"; } } } voidenqueue(structpointp)迷宫中队列入队操作 { queue[tail]=p; tail++;先用再加,队列尾部加1 } structpointdequeue()迷宫中队列出队操作,不需要形参,因此用结构体定义 { queue[)路径求解 { X=1;初始值定为1 structpointp={0,0,-1};定义入口节点 if(maze[p.row][p.col]==1)入口为1时,迷宫不可解 { cout<<"\n===============================================\n"; cout<<"此迷宫无解\n\n"; X=0; return0; } maze[p.row][p.col]=2;标记为已访问 enqueue(p);将p入队列 while(! is_empty()) { p=dequeue(); if((p.row==m-1)&&(p.col==n-1))当行和列为出口时跳出 3.5限制条件 在输入值时必须按照程序所规定的输入,否则将运行错误或无法运行。 第四章软件使用说明 4.1软件使用说明及出现的问题 运行环境为MicrosoftVisualC++6.0 输出界面有三个选项,1为手动生成迷宫,2为自动生成迷宫,3为推出程序。 当程序运行时,设cycle为0,当选择3退出程序时,cycle为-1。 选择自动生成迷宫时,只需输入想要迷宫的行数.列数。 在输出界面上,起初,仅仅是将最终结果展示,而无矩阵的规范输出,即如果使用者手输出迷宫时,并未整齐的输入迷宫,如果此时显示迷宫最后的路径,使使用者不易清晰的看出路径而难以理解。 基于站在使用者的角度,加入了data函数,实现了数组、符号、数位路径、字符路径共同出现的最终界面,并在输出时添加相应的箭头指示,在输出的迷宫图时将最外层加入的围墙用“▲”表示,经多次修改,使得输出界面整洁大方。 4.2运行结果 图4—1欢迎界面 图4—1测试结果—迷宫有解 图4—1测试结果—迷宫有解 第五章课程设计心得与体会 在程序编写的过程中,发现了很多问题及错误。 例如,程序刚形成雏形时,经测试,程序只能实现8*8的迷宫矩阵寻路,并且会出现寻路时跳出迷宫的情况。 因此,程序员在此基础上,将迷宫矩阵数组由原来的maze[10][10]改为maze[N+2][M+2],并在相应函数上加以大量改动,最终使本程序实现了程序本身范围内的任意N*M迷宫矩阵组合的寻路求解。 在输出界面上,起初,仅仅是将最终结果展示,而无矩阵的规范输出,即如果使用者手输出迷宫时,并未整齐的输入迷宫,如果此时显示迷宫最后的路径,使使用者不易清晰的看出路径而难以理解。 基于站在使用者的角度,加入了data函数,实现了数组、符号、数位路径、字符路径共同出现的最终界面,并在输出时添加相应的箭头指示,在输出的迷宫图时将最外层加入的围墙用“▲”表示,经多次修改,使得输出界面整洁大方。 在最开始判断搜索方向的时候,我们列出的八个方向并未按照一定顺序搜索,此时就会出现错误,后来采用一定顺序来完成迷宫的搜索,因为设定迷宫的入口在左上方,出口在右下方,所以采用顺时针方向比采用逆时针方向能最先找出最短路径。 所以最后采用了顺时针的搜索方向,即沿北、东北、东、东南、南、西南、西、西北八个方向搜索。 在测试输出结果方面,出了一个困扰我们一阵时间的问题,在以5*7自动生成迷宫矩阵的测试过程中,几乎每隔几次都会出现一次这样类似的问题(见下图),在下图的输出界面 图5—1 以及字符展示界面中,经过简单的分析,便可以得出最后通往出口的道路,但在程序判断并输出路径后,在图中可以看到: 五角星所标记的走过的路,在出口处出现了错误。 但是此程序手动输入的时候不会出现任何错误,所以问题锁定在自动生成迷宫函数中。 在此,我们列出当时的自动生成迷宫函数: voidautomatic_maze(intm,intn) { inti,j; cout<<"\n迷宫生成中……\n\n"; system("pause"); for(i=0;i for(j=0;j maze[i][j]=rand()%2; maze[0][0]=0; maze[i-1][j-1]=0; } 在修改过程中,反复分析了各个函数后将问题锁定在自动生成函数处。 观察此函数,发现“maze[i-1][j-1]=0;”是导致问题的最终所在。 该语句的初衷是将迷宫矩阵中最初一个数判定为0,防止出现迷宫出口不通的情况。 在这儿以5*7迷宫为例,经过分析,当跳出for循环时,i=5,j=6,而要改变的数是maze[5][7],而非maze[5][6],这也就是导致上图所示结果的原因,将该语句改为maze[m-1][n-1],问题解决。 附录一: 参考文献 [1]、谭浩强,C++程序设计,北京: 清华大学出版社出版,2004年6月 [2]、谭浩强,C++程序设计题解与上机指导,北京: 清华大学出版社出版,2005年3月 [3]、姜灵芝、余健,C语言课程设计案例精编,北京: 清华大学出版社,2008年1月 [4]、严华峰,VisualC++课程设计案例精编,北京: 中国水利水电出版社出版,2002年 附录二: 源代码 #include { inti,j; cout< cout<<"请按行输入迷宫,0表示通路,1表示障碍: "< for(i=0;i for(j=0;j { cin>>maze[i][j]; } } voidautomatic_maze(intm,intn)自动生成迷宫 { inti,j; cout<<"\n迷宫生成中……\n\n"; system("pause"); for(i=0;i for(j=0;j maze[i][j]=rand()%2;随机生成0、1 maze[0][0]=0;将开始和结束位置强制为0,保证有可能出来迷宫 maze[m-1][n-1]=0; } voiddata(intm,intn) {当用户输入的不是规整的m行n列的迷宫,用来生成规则的数字迷宫 inti,j; cout< cout<<"根据您先前设定的迷宫范围"< cout< cout<<"我们将取所输入的前"< cout<<"\n数字迷宫生成结果如下: \n\n"; cout<<"迷宫入口\n"; cout<<"↓"; for(i=0;i { cout<<"\n"; for(j=0;j { if(maze[i][j]==0) cout<<"0"; if(maze[i][j]==1) cout<<"1"; } } cout<<"→迷宫出口\n"; } voidprint_maze(intm,intn) {打印迷宫外壳 inti,j,k; cout<<"\n字符迷宫生成结果如下: \n\n"; cout<<"迷宫入口\n"; cout<<"↓"; cout< cout<<"▲";生成上外壳 for(k=0;k { cout<<"▲";这两个黑三角用来生成顶部外壳 } for(i=0;i { cout<<"\n";生成左外壳 cout<<"▲"; for(j=0;j { if(maze[i][j]==0)printf("□"); if(maze[i][j]==1)printf("■"); } cout<<"▲";生成右外壳 } cout< for(k=0;k { cout<<"▲"; } cout<<"▲\n";生成底部外壳 for(i=0;i {cout<<"";} cout<<"↓\n"; for(i=0;i {cout<<"";} cout<<"迷宫出口\n"; } voidresult_maze(intm,intn)这个是打印输出迷宫的星号路径 { inti,j; cout<<"迷宫通路(用☆表示)如下所示: \n\t"; for(i=0;i { cout<<"\n"; for(j=0;j { if(maze[i][j]==0||maze[i][j]==2)2是队列中访问过的点 cout<<"□"; if(maze[i][j]==1) cout<<"■"; if(maze[i][j]==3)3是标记的可以走通的路径 cout<<"☆"; } } } voidenqueue(structpointp)迷宫中队列入队操作 { queue[tail]=p; tail++;先用再加,队列尾部加1 } structpointdequeue()迷宫中队列出队操作,不需要形参,因此用结构体定义 { queue[)路径求解 { X=1;初始值定为1 structpointp={0,0,-1};定义入口节点 if(maze[p.row][p.col]==1)入口为1时,迷宫不可解 { cout<<"\n===============================================\n"; cout<<"此迷宫无解\n\n"; X=0; return0; } maze[p.row][p.col]=2;标记为已访问 enqueue(p);将p入队列 while(! is_empty()) { p=dequeue(); if((p.row==m-1)&&(p.col==n-1))当行和列为出口时跳出 break; 定义8个走位方向 if((((p.row-1)>=0)&&((p.row-1) visit(p.row-1,p.col+0,maze);北 if((((p.row-1)>=0)&&((p.row-1) visit(p.row-1,p.col+1,maze);东北 if((((p.row+0) visit(p.row+0,p.col+1,maze);东 if((((p.row+1) visit(p.row+1,p.col+1,maze);东南 if((((p.row+1) visit(p.row+1,p.col+0,maze);南 if((((p.row+1) visit(p.row+1,p.col-1,maze);西南 if((((p.row+0) visit(p.row+0,p.col-1,maze);西 if((((p.row-1)>=0)&&((p.row-1) visit(p.row-1,p.col-1,maze);西北 } if(p.row==m-1&&p.col==n-1)如果当前矩阵点是出口点,输出路径 { cout<<"\n==================================================================\n"; cout<<"迷宫路径为: \n"; cout<<"出口"< cout<<""<<"↑"< printf("(%d,%d)\n",p.row+1,p.col+1); cout<<""<<"↑"< maze[p.row][p.col]=3;逆序将路径标记为3 while(p.predecessor! =-1) { p=queue[p.predecessor]; printf("(%d,%d)\n",p.row+1,p.col+1); cout<<""<<"↑"< maze[p.row][p.col]=3; } cout<<"入口"< } else { cout<<"\n=============================================================\n"; cout<<"此迷宫无解! \n\n"; X=0; } return0; } voidmain() { inti,m,n,cycle=0; while(cycle! =(-1)) { cout<<"********************************************************************************\n"; cout<<"欢迎进入迷宫求解系统\n"; cout< cout<<"设计者: 杨晓辉(计算机092202H班)\n"; cout<<"********************************************************************************\n"; cout<<"☆手动生成迷宫请按: 1\n"; cout<<"☆自动生成迷宫请按: 2\n"; cout<<"☆退出请按: 3\n\n"; cout<<"********************************************************************************\n"; cout<<"\n"; cout<<"请选择你的操作: \n"; cin>>i; switch(i) { case1: cout<<"\n请输入行数: "; cin>>m; cout<<"\n"; cout<<"请输入列数: "; cin>>n; while((m<0||m>49)||(n<0||n>49)) { cout<<"\n抱歉,你输入的行列数超出预设范围(),请重新输入: \n\n"; cout<<"\n请输入行数: "; cin>>m; cout<<"\n"; cout<<"请输入列数: "; cin>>n; } ); data(m,n); print_maze(m,n); path(maze,m,n); if(X! =0)result_maze(m,n);当X不为0时,有解,调用输出路径函数 cout<<"\n\nPressEnterContiue! \n"; getchar(); while(getchar()! ='\n');接受一个输入,当为回车时执行break跳出,否则一直执行接受数据 break; case2: cout<<"\n请输入行数: "; cin>>m; cout<<"\n"; cout<<"请输入列数: "; cin>>n; while((m<0||m>49)||(n<0||n>49)) { cout<<"\n抱歉,你输入的行列数超出预设范围(),请重新输入: \n\n"; cout<<"\n请输入行数: "; cin>>m; cout<<"\n"; cout<<"请输入列数: "; cin>>n; } automatic_maze(m,n); data(m,n); print_maze(m,n); path(maze,m,n); if(X! =0)result_maze(m,n); cout<<"\n\nPressEnterContiue! \n"; getchar(); while(getchar()! ='\n'); break; case3: cycle=(-1);break; default: cout<<"\n";cout<<"你的输入有误! \n"; cout<<"\nPressEnterContiue! \n"; getchar(); while(getchar()! ='\n'); break; } } }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 完整版 C+ 毕业 课程设计 自动 迷宫 小游戏