贪吃蛇课程设计实验报告模板9.doc_第1页
贪吃蛇课程设计实验报告模板9.doc_第2页
贪吃蛇课程设计实验报告模板9.doc_第3页
贪吃蛇课程设计实验报告模板9.doc_第4页
贪吃蛇课程设计实验报告模板9.doc_第5页
已阅读5页,还剩20页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

荆楚理工学院 课程设计成果 学院: 计算机工程学院 _班级: 计算机科学与技术一班 学生姓名: 焦润 学号:2013404010107 设计地点(单位):A5201 设计题目:贪吃蛇游戏 完成日期: 2015 年 07 月 05 日 指导教师评语:_ 成绩(五级计分制)_教师签名_ 目录一、需求分析31.1设计目的31.2设计内容3二、概要设计4三、详细设计5四、测试分析12五、用户使用说明15六、总结156.1、需求分析方面156.2、数据结构156.3、遇到的问题157、附录(程序源代码)161、 需求分析1.1设计目的 贪吃蛇是家喻户晓的益智类小游戏,选择这个题目一是为了将我们所学的知识加以运用,二是一直以来贪吃蛇这个小游戏就比较吸引人,它的实现对于以前的我们而言都是很神秘的。我们希望通过自己所学的知识把它剖析开来,真真正正地了解它的本质和精髓。同时更进一步地掌握c语言、c+(本实验是用c+进行开发的)以及数据结构的理论知识与实际应用,熟悉基本的游戏软件开发过程。根据分析后的贪吃蛇结构设计出相应的游戏流程,主要内容包括:游戏开始,定义活动范围(Map),随机出现食物,方向控制,游戏结束,分数以及难度的显示。1.2设计内容1.通过输入地图长度、宽度,划出snake活动的区域,同时选择游戏难度,游戏难度通过移动速度来决定。2.食物的随机生成3. 用键盘上的WASD键对snake的活动方向进行控制。蛇身方向的处理,控制蛇头的移动,定一个双向链表,用来保管每次移动完以后,每一节蛇身的位置,下一次的时候,每一个蛇身读取前一个蛇身的坐标,就可以实现蛇的整体移动。移动完以后,新的坐标被保管进数组,如此一直循环下去。选择的数据结构:双向链表、队列、广度优先搜索4.撞墙和撞到本身,撞墙判断蛇头坐标是否到边界。撞到本身,做一个循环判断蛇头的坐标是否和其他蛇身相等。流程图如下:二、概要设计功能块各函数列表:bool Auto:bfs(int sx,int sy,int ex,int ey)/广度优先搜索函数,用于搜索路径void snake:add_head(int xx,int yy)/增加蛇头结点void snake:del_tail()/删除蛇尾结点void Map:initMap()/初始化地图void Map:outputMap()/打印出游戏当前的状态void move:get_food()/随机生成食物int move:movesnake()/移动蛇身bool move:turn_dir(char op)/snake移动方向控制bool game()/开始游戏,设置地图,并选择游戏模式void welcome()/进入游戏结构体细分功能:struct point int x,y,step;/储存搜索状态 int path900;struct snake_node int x;/蛇头结点横坐标 int y;/蛇头结点纵坐标 int rank;/第几个蛇结点;三、详细设计/广度优先搜索函数bool Auto:bfs(int sx,int sy,int ex,int ey) /BFS在选择 自动 后,调用该函数搜索 point in,out; int i,j,step,x,y,way,len; int d42=-1,0,1,0,0,-1,0,1; int g84=0,1,2,3, 0,3,1,2, 3,2,0,1, 1,2,0,3, 1,3,0,2, 2,1,3,0, 2,0,3,1, 3,1,0,2; memset(vis,0,sizeof(vis); memset(path,0,sizeof(path); list:iterator it=s.l.begin(); for(;it!=s.l.end();it+) x=it-x; y=it-y; visxy=it-rank; in.x=sx; in.y=sy; in.step=0; len=s.l.size(); while(!q.empty() q.pop(); q.push(in); while(!q.empty() out=q.front(); q.pop(); if(out.x=ex & out.y=ey) for(j=0;jout.step;j+) pathj=out.pathj; return true; step=out.step+1; way=rand()%8; for(i=0;i=len ) visxy=visout.xout.y+1; in.x=x; in.y=y; in.step=step; for(j=0;jrank+1; l.push_front(temp); /以下 用于改变蛇头图标 和 第二个蛇结点图标 if(m.dir=up) f.mapxxyy=30; else if(m.dir=down) f.mapxxyy=31; else if(m.dir=lef) f.mapxxyy=17; else f.mapxxyy=16; if(l.size()1) list:iterator it; it=l.begin(); it+; xx=it-x; yy=it-y; f.mapxxyy=body; /删除蛇尾结点函数void snake:del_tail() int xx,yy; list:iterator it; it=l.end(); it-; xx=it-x; yy=it-y; f.mapxxyy= ; /将蛇尾变为 l.erase(it);/初始化地图函数void Map:initMap() for(int i=0;imap_len;i+) for(int j=0;jmap_wide;j+) if(i=0 | i=map_len-1 | j=0 | j=map_wide-1) mapij=#; else mapij= ; /打印函数void Map:outputMap() for(int i=0;imap_len;i+) for(int j=0;j1)-2)printf(t当 前 得 分 : %d,m.num); if(i=(map_len1) printf(t当 前 难 度 : %d,m.lv); if(i=(map_len1)+2)printf(t 最 高 分 : %d,Best_score); puts(); /随机生成食物函数void move:get_food() struct empty_gard int x,y; temp900; int tnum=0; for(int i=1,len=map_len-1;ilen;i+) /把空格找出来 for(int j=1,wide=map_wide-1;jx; int y=s.l.begin()-y; if(dir=up) x-; /根据方向移动蛇 if(dir=down) x+; if(dir=lef) y-; if(dir=rig) y+; if(f.mapxy!= & f.mapxy!=food) f.outputMap();PlaySound(TEXT(death.wav), NULL, SND_ASYNC | SND_NODEFAULT); /播放音乐的 puts(nnttGAME OVER!nn); puts(nnPlay Again? YES press Y ; NO press OtherKeynn); if(m.numBest_score) Best_score=m.num; char op; op=getch(); if(op=Y | op=y) return 1; else return 0; else if(f.mapxy=food) PlaySound(TEXT(eat.wav), NULL, SND_ASYNC | SND_NODEFAULT); s.add_head(x,y); num+; get_food(); if(num & num%3=0 & lvmost_difficult) /每吃3个食物难度+1 lv-; else s.add_head(x,y); s.del_tail(); return 2; /返回2表示没game over 继续游戏 /控制移动方向函数bool move:turn_dir(char op) if(op=w | op=W | op=1) & dir!=down) dir=up;return true; if(op=s | op=S | op=2) & dir!=up) dir=down;return true; if(op=a | op=A | op=3) & dir!=rig) dir=lef;return true; if(op=d | op=D | op=4) & dir!=lef) dir=rig;return true; return false;/开始游戏函数bool game() int temp; cout输入地图长度(1030):map_len; if(10=map_len & map_len=30) break; coutInput Againendl; cout输入地图宽度(1030):map_wide; if(10=map_wide & map_wide=30) break; coutInput Againendl; while(true) cout选择游戏难度(Lv.most_difficult20 等级越低,难度越大):m.lv; m.num=(20-m.lv)*3; if(most_difficult=m.lv & m.lv=20) break; coutInput Again1; /下面几句用来初始化游戏 加入两个蛇结点和第一个食物 int mid_y=map_wide1; s.add_head(mid_x,mid_y); s.add_head(mid_x,mid_y+1); m.get_food(); f.outputMap(); puts(t用W S A D 控制蛇的前进方向,难度会随着分数变得困难。); char op=getch(); if(op=y | op=Y) while(1) /选择自动模式 一直调用bfs()搜索路径直到所不到可行方案为止 bool gzx; for(int i=0;ix,s.l.begin()-y,m.food_x,m.food_y); if(gzx) break; if(gzx) int l=strlen(w.path); for(int i=0;il;i+) system(cls); m.turn_dir(w.pathi); /将搜索到的路径(方向) 逐个用来调用turn_dir() 然后移动一步 if(temp=m.movesnake()=0) return false; else if(temp=1) return true; f.outputMap(); Sleep(m.speedm.lv); else /如果选择自由模式后BFS搜索不到路径就执行else里面的代码 即:按一个方向直接 撞墙去 while(1) system(cls); if(temp=m.movesnake()=0) return false; else if(temp=1) return true; f.outputMap(); Sleep(m.speedm.lv); system(cls); /选择玩家模式后执行下面代码 kbhit() getch() f.outputMap(); while(1) op=getch(); bool work=m.turn_dir(op);if(work) PlaySound(TEXT(turn.wav), NULL, SND_ASYNC | SND_NODEFAULT); while(!kbhit() system(cls); if(temp=m.movesnake()=0) return false; else if(temp=1) return true; f.outputMap(); Sleep(m.speedm.lv); 四、测试分析4.1首页面4.2进入游戏页面,设置地图长度宽度及游戏难度4.3选择游戏模式界面4.4选择自动模式或玩家模式,喂饱snake的肚子4.5游戏结束页面,可以选择继续或者退出五、用户使用说明开发环境:VC+6.0运行环境:VC+6.0游戏操作:进入首页后根据提示操作六、总结:6.1、需求分析方面:在分析问题过程中总会不断遇到新的要求、新的挑战。在这个分析过程中,对于实验的要求和实验的目的是明确的,但在具体讨论到功能的实现时产生了两大难题:一是蛇身的处理,二是如何移动及移动路径。这两个问题后来通过数据结构中的双向链表和广度优先搜索的只是得到了较好的解决。根据分析后的贪吃蛇结构设计出相应的游戏流程,主要内容包括:游戏开始,定义活动范围(Map),随机出现食物,方向控制,游戏结束,分数以及难度的显示等,游戏流程还是比较简洁清晰的。6.2、数据结构对实验需要实现功能经过分析后得出此次实验需要用到的数据结构有双向链表和队列,其中还引用了广度优先搜索的内容,其中双向链表用于保存整个贪吃蛇每节蛇身位置,队列和广度优先遍历则是在玩家选择了自动模式后,实验用于查找贪吃蛇的路径,自动进行游戏。在存储结构方面,比如说游戏的最高分,则是以文件读取形式为主,在游戏结束后将分数与历史最高分进行比较,若分数高于历史最高分,则改写文件中保存分数的内容。6.3、遇到的问题 在本次实验中主要遇到了如何保存游戏历史最高分和如何让游戏自动运行的问题。由于游戏每次开始都会现实历史最高分,而历史最高分是随着游戏的每次进行而时时更新的,所以不能在程序内部进行保存,所以选择了运用文件进行保存操作。另外,为了让游戏能够自动运行,即使贪吃蛇能够自动行走,经过小组的商讨,决定运用数据结构中的广度优先搜索函数,用于对路径的搜索。以上便是在设计实验的过程所遇到的问题和小组讨论的解决方案。7、附录(程序源代码)#include#include#include#include#include#include#include#include#include#include#include#pragma comment(lib, winmm.lib)using namespace std;const int up=1;const int down=2;const int lef=3;const int rig=4;const char body=4;const char food=2;const int most_difficult=0;int map_len,map_wide,Best_score;bool flag;FILE *fp;class Auto public: int vis3131; /BFS判重用 char path1000; /存储BFS搜索出结果后的路径 typedef struct point int x,y,step; int path900; ; queue q; public: bool bfs(int,int,int ,int);w;class Map public: char map3131; public: Map(); /Map()等和类名相同的 函数是构造函数 用于对象的初始化 下同 Map(); /析构函数 加上 类名() 作用是在释放对象前做清理工作 和free()类似 void outputMap(); /打印出游戏当前的状态 void initMap(); /初始化地图 f;class snake public: typedef struct snake_node int x; int y; int rank; ; list l; /stl list(相当有双向链表) 用于存储蛇上的所有结点 public: snake(); snake(); void add_head(int ,int ); /增加蛇头结点 void del_tail(); /删除蛇尾结点 s;class move public: int dir; /当前蛇的前进方向 int num; /当前吃到食物的数量 int lv; /当前难度 int speed21; /存储速度(难度)系数 int food_x; /当前食物的坐标 int food_y; public: move(); move(); int movesnake(); /调用add_head() 和 del_tail() 来移动一步蛇 void turn_dir(char); /根据输入改变蛇的前进方向 void get_food(); /当食物被吃掉时候 重新生成一个食物 m;Map:Map() memset(map,0,sizeof(map);Map:Map()move:move() dir=rig; num=0; lv=0; for(int i=1;i=20;i+) speedi=50*i; speed0=10;move:move()snake:snake() l.clear();snake:snake()bool Auto:bfs(int sx,int sy,int ex,int ey) /BFS在选择 自动 后,调用该函数搜索 point in,out; int i,j,step,x,y,way,len; int d42=-1,0,1,0,0,-1,0,1; int g84=0,1,2,3, 0,3,1,2, 3,2,0,1, 1,2,0,3, 1,3,0,2, 2,1,3,0, 2,0,3,1, 3,1,0,2; memset(vis,0,sizeof(vis); memset(path,0,sizeof(path); list:iterator it=s.l.begin(); for(;it!=s.l.end();it+) x=it-x; y=it-y; visxy=it-rank; in.x=sx; in.y=sy; in.step=0; len=s.l.size(); while(!q.empty() q.pop(); q.push(in); while(!q.empty() out=q.front(); q.pop(); if(out.x=ex & out.y=ey) for(j=0;jout.step;j+) pathj=out.pathj; return true; step=out.step+1; way=rand()%8; for(i=0;i=len ) visxy=visout.xout.y+1; in.x=x; in.y=y; in.step=step; for(j=0;jrank+1; l.push_front(temp); /以下 用于改变蛇头图标 和 第二个蛇结点图标 if(m.dir=up) f.mapxxyy=30; else if(m.dir=down) f.mapxxyy=31; else if(m.dir=lef) f.mapxxyy=17; else f.mapxxyy=16; if(l.size()1) list:iterator it; it=l.begin(); it+; xx=it-x; yy=it-y; f.mapxxyy=body; void snake:del_tail() int xx,yy; list:iterator it; it=l.end(); it-; xx=it-x; yy=it-y; f.mapxxyy= ; /将蛇尾变为 l.erase(it);void Map:initMap() for(int i=0;imap_len;i+) for(int j=0;jmap_wide;j+) if(i=0 | i=map_len-1 | j=0 | j=map_wide-1) mapij=#; else mapij= ; void Map:outputMap() for(int i=0;imap_len;i+) for(int j=0;j1)-2)printf(t当 前 得 分 : %d,m.num); if(i=(map_len1) printf(t当 前 难 度 : %d,m.lv); if(i=(map_len1)+2)printf(t 最 高 分 : %d,Best_score); puts(); void move:get_food() struct empty_gard int x,y; temp900; int tnum=0; for(int i=1,len=map_len-1;ilen;i+) /把空格找出来 for(int j=1,wide=map_wide-1;jx; int y=s.l.begin()-y; if(dir=up) x-; /根据方向移动蛇 if(dir=down) x+; if(dir=lef) y-; if(dir=rig) y+; if(f.mapxy=food) PlaySound(TEXT(eat.wav), NULL, SND_ASYNC | SND_NODEFAULT); s.add_head(x,y); num+; get_food(); if(num & num%3=0 & lvmost_difficult) /没吃3个食物难度+1 lv-; else if(f.mapxy!= & f.mapxy!=food) f.outputMap();PlaySound(TEXT(death.wav), NULL, SND_ASYNC | SND_NODEFAULT); /播放音乐的 puts(nnttGAME OVER!nn);fp=fopen(score.txt,w);fprintf(fp,%dn,Best_score);fclose(fp); puts(nnPlay Again? YES press Y ; NO press OtherKeynn); if(m.numBest_score) Best_score=m.num; char op; op=getch(); if(op=Y | op=y) return 1; else return 0; else s.add_head(x,y); s.del

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论