已阅读5页,还剩11页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
(一) 需求分析 题目:32、实现一个 N*M 的扫雷游戏设计要求:能够实现一个 N*M 的扫雷游戏a、能够打开一个方格(由于做的是静态显示,故在控制台上方格用代替),已打开的方格不能关闭b、能够标记一个方格,标记方格的含义是对该方格有雷的预测(并不表示真的一定有雷)c、能够给出游戏结果:输、赢d、N和M可由玩家自己设置系统功能需求分析:一个数字和一个雷(boom)。你可以打开(open)一个方格,如果你打开的是 一个boom,那么就失败;否则就会打开一个数字,该数字是位于0,8的一个整数,该数字表示其所有 邻居方格所包含的雷数,应用该信息可以帮助你扫雷。点击到了某区域发现其周围没有雷,那么显而易见应该点开周围的区域,拓展空白区域 (二)概要设计由于知识储备不足,VC中的MFC应用程序又过于复杂,故退而求其次,不再采用动态显示和界面图形化,采用静态显示来实现扫雷游戏中的主要功能。用键盘上的1键代替鼠标左击,即打开一个方格查看其属性,已打开的方格不能在关闭;用键盘上的2键代替鼠标右击,即标记一个方格,标记方格的含义是对该方格有雷的预测(并不表示真的一定有雷)用键盘上的四个键来实现光标在控制台上的自由移动,相当于用鼠标实现光标在图形界面的移动游戏区域的高度与宽度及总雷数可由玩家自己设定应题目要求设计了一个基类:Base和一个继承类:Game。基类Base主要实现一些基本功能:游戏结束时输出游戏的结果:输赢;返回控制台上光标的位置返回按下键时所对应的按键控制符基类Base:类名成员类别类型成员名描述Base方法static intOutput(const char*)在当前位置上输出一串字符static intGotoXY(int, int);取得控制台上光标的坐标位置并返回static intGetKey();等待按下键,并返回所对应的按键控制符继承类Game是本程序的主要内容,也是实现扫雷游戏的关键部分。主要实现的功能:初始化图形界面,把游戏区域在控制台上显示出来;利用随机函数进行随机布雷,以保证玩家每次玩游戏时雷的分布位置均不同;得到一个坐标位置周围的雷数,并把数值返回;在一个坐标点上(x,y)点击,在该位置上显示其周围的雷数或拓展空白区域或失败;如果一个坐标点的周围没有雷,则拓展空白区域,并递归拓展;其中saolei()函数是类Game里的关键函数体,用来判断玩家按下了哪个键,并作出相应反应(上下左右四个方向的移动,打开一个方格,标记一个方格),并判断游戏的输与赢继承类Game:类名成员类别类型成员名描述Game属性intcurX,curY光标位置intpoolWidth,poolHeight游戏区域的高度与宽度intpoolGAME_MAX_HEIGHT+1GAME_MAX_WIDTH+1用二维数组来存储雷的相关属性const static intGMARK_BOOM;GMARK_EMPTYGMARK_MARK;雷的属性:雷(*),空,标记(#)方法intinitpool(int,int,int)初始布雷IntMoveCursor()移动光标inthuatu(int)在控制台上把扫雷区域显示出来inttryopen(int,int)在一个坐标点上(x,y)点击,在该位置上显示其周围的雷数或拓展空白区域或失败intshownum(int,int)得到一个坐标位置周围的雷数,并把数值返回inttuozhan(int,int)如果一个坐标点的周围没有雷,则拓展空白区域,并递归拓展intsaolei()扫雷并判断输赢(三)详细设计核心算法:(1)布雷函数:初始化时把数组里的值全部置为0,然后利用srand(),rand()随机机制产生随机数,分别对列和行取模,便产生了雷的随机位置。但是布雷前,先要判断此随机位置是否已经布上了雷。int Game:initpool(int width,int height,int num)poolWidth=width;poolHeight=height;if(num=width*height|widthGAME_MAX_HEIGHT|width=0|heightGAME_MAX_HEIGHT)return 1;/初始是把游戏区域也即是数组里的值全都置为0for(int y=0;y=height+1;y+)for(int x=0;x=width+1;x+)poolyx=0;/利用伪随机函数进行随机布雷,以保证每次点击游戏时雷的分布位置不同srand(time(NULL);while(num!=0)int x=rand()%width+1;int y=rand()%height+1;if(poolyx=0)poolyx=GMARK_BOOM;num-;/num为设置的总雷数/初始化光标位置 curX=1;curY=1; MoveCursor(); return 0;(2)打开方格,查看方格的属性/在该位置上显示其周围的雷数或拓展空白区域或失败int Game:tryopen(int x,int y)int m=0;if(poolyx & GMARK_BOOM)m=-1;elseint count=shownum(x,y);if(count=0)tuozhan(x,y);/拓展空白区域else poolyx=count;return m;(3)获得周围雷的数目扫描其周围的所有相邻方格,记录雷数,并把值返回;扫描前要选择合理的起始点 int Game:shownum(int x,int y)int count=0;for(int Y=-1;Y=1;Y+)for(int X=-1;X0&x0&y=poolHeight)&(poolyx=0)int count=shownum(x,y);if(count=0)poolyx=GMARK_EMPTY;for(int Y=-1;Y=1;Y+)for(int X=-1;X=1;X+)tuozhan(x+X,y+Y);else poolyx=count;return 0;(5)在控制台上把扫雷区域显示出来在还未按键时,调用huatu()函数把游戏界面在控制台上显示出来,即全部显示为方格。以后每按键一次。刷新一次界面int Game:huatu(int n=0)for(int y=1;y=poolHeight;y+)Base:GotoXY(1,y);for(int x=1;x0 & poolyx=8)putchar(0+poolyx);else if(n=0 & (poolyx& GMARK_MARK) )putchar(#);else if(poolyx& GMARK_BOOM)if(n!=0)putchar(*);elseputchar(.);return 0;(6)判断是否胜利判断游戏是否胜利的条件在saolei()函数体内,在主函数里调用saolei()进行循环,直到戏赢了或输了才退出循环,并在控制台上输出结果;游戏赢了返回1,按下ESC键退出游戏返回-1,记为输,扫到雷也是返回-1判断是否赢了游戏:按下键1后,对整个游戏区域进行检测,如果检测不到值为0的方格,即所有的雷已被扫出,则返回1,游戏胜利;按下ESC键退出游戏和扫到雷均为输,返回-1if(Key = KEY_1 )/判断是否赢了游戏 int y=1; for(;y=poolHeight;+y) int x=1; for(;x=poolWidth; +x) if(poolyx=0)break; if(x=poolWidth) break; if(! (y=poolHeight) m = 1; (四)调试分析及测试(1)由玩家设置游戏区域的高度与宽度,并设置总雷数按下回车键后界面如下: 按下键1开始扫雷,扫雷过程部分界面如下:游戏输时显示的结果:(2)直接按下ESC键时输掉游戏:然后按下回车键后,直接按下ESC键,结果如下:(3)为了使快速赢得游戏,减少雷的数目:游戏运行过程部分界面如下:按下键2对怀疑有雷的区域进行标记游戏胜利时显示的界面:(五)源程序附录源程序:#include#include#include/包含伪随机数发生函数#include/包含返回一个字符在控制台屏幕上坐标的文件#include/包含getch()库函数:从控制台读取一个字符,但不显示在屏幕上/#define 定义的一些宏变量/键盘上上、下、左、右四个键及一些按键对应的ASCII编码#define KEY_UP 0xE048 #define KEY_DOWN 0xE050#define KEY_LEFT 0xE04B#define KEY_RIGHT 0xE04D#define KEY_ESC 0x001B#define KEY_1 1#define KEY_2 2/设置游戏区域的最大长度与高度#define GAME_MAX_WIDTH 100#define GAME_MAX_HEIGHT 100/游戏初始时在控制台上输出的游戏提示#define GAMETITLE ArrowKey:MoveCursor KEY1:Open Key2:Mark/当游戏结束时输出的字符#define GAMEWIN Congratulations! You Win! Thank you for playing!n#define GAMEOVER Sorry,you lose! thank you for playing!n #define GAMEEND Press ESC to exitn/基类/ Base classclass Base public: static int Output(const char*); static int GotoXY(int, int); static int GetKey(); ; int Base:GetKey()/等待按下键,并返回所对应的按键控制符 int nkey=getch(),nk=0; if(nkey=128|nkey=0)nk=getch();/等待你按下任意键后,把该键字符所对应的ASCII符付给nk后,在执行下面语句 return nk0?nkey*256+nk:nkey; int Base:GotoXY(int x, int y)/取得控制台上光标的坐标位置并返回 COORD cd; cd.X = x;cd.Y = y; return SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),cd); int Base:Output(const char* pstr)/在当前位置上输出一串字符 for(;*pstr;pstr+)putchar(*pstr);/函数向标准输出设备输出一个变量的字符形式 return 0; /继承class Game:public Base private: int curX,curY; int poolWidth,poolHeight;/雷区间的总高度与宽度,相当与height int poolGAME_MAX_HEIGHT+2GAME_MAX_WIDTH+2; public: Game():curX(0),curY(0)poolWidth=poolHeight=0; int initpool(int,int,int);/初始化游戏区域,设置游戏区域的高度与宽度,并设置总雷数int MoveCursor()return Base:GotoXY(curX,curY);int huatu(int);/在控制台上把扫雷区域显示出来int shownum(int,int);/得到一个坐标位置周围的雷数,并把数值返回int tryopen(int,int);/在一个坐标点上(x,y)点击,在该位置上显示其周围的雷数或拓展空白区域或失败int saolei(); private: int tuozhan(int, int);/如果一个坐标点的周围没有雷,则拓展空白区域,并递归拓展 private: const static int GMARK_BOOM; const static int GMARK_EMPTY; const static int GMARK_MARK; const int Game:GMARK_BOOM = 0x10; /*所对应的ASCII编码 ,用*表示地雷 const int Game:GMARK_EMPTY= 0x100;/空白所对应的ASCII编码 const int Game:GMARK_MARK = 0x200;/#所对应的ASCII编码,用#表示作标记int Game:initpool(int width,int height,int num)poolWidth=width;poolHeight=height;if(num=width*height|widthGAME_MAX_HEIGHT|width=0|heightGAME_MAX_HEIGHT)return 1;/初始是把游戏区域也即是数组里的值全都置为0for(int y=0;y=height+1;y+)for(int x=0;x=width+1;x+)poolyx=0;/利用伪随机函数进行随机布雷,以保证每次点击游戏时雷的分布位置不同srand(time(NULL);while(num!=0)int x=rand()%width+1;int y=rand()%height+1;if(poolyx=0)poolyx=GMARK_BOOM;num-;/num为设置的总雷数/初始化光标位置 curX=1;curY=1; MoveCursor(); return 0; /在控制台上把扫雷区域显示出来 int Game:huatu(int n=0)for(int y=1;y=poolHeight;y+)Base:GotoXY(1,y);for(int x=1;x0 & poolyx=8)putchar(0+poolyx);else if(n=0 & (poolyx& GMARK_MARK) )putchar(#);else if(poolyx& GMARK_BOOM)if(n!=0)putchar(*);elseputchar(.);return 0; /得到一个坐标位置周围的雷数,并把数值返回 int Game:shownum(int x,int y)int count=0;for(int Y=-1;Y=1;Y+)for(int X=-1;X0&x0&y=poolHeight)&(poolyx=0)int count=shownum(x,y);if(count=0)poolyx=GMARK_EMPTY;for(int Y=-1;Y=1;Y+)for(int X=-1;X1)curY-; nArrow=1; break; case KEY_DOWN: if(curY1)curX-; nArrow=1; break; case KEY_RIGHT: if(curXpoolWidth)curX+; nArrow=1; break; case KEY_1: m = tryopen(curX, curY); break; case KEY_2: if(poolcurYcu
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025江苏省建筑安全员B证考试题库附答案
- 贵州财经职业学院《生殖医学》2023-2024学年第一学期期末试卷
- 贵阳职业技术学院《编排与版式》2023-2024学年第一学期期末试卷
- 2025年贵州建筑安全员《A证》考试题库及答案
- 2025年陕西建筑安全员《B证》考试题库
- 2025年天津建筑安全员《B证》考试题库
- 广州中医药大学《管理沟通双语》2023-2024学年第一学期期末试卷
- 2025江苏省安全员《B证》考试题库
- 广州医科大学《机械制造技术课程设计》2023-2024学年第一学期期末试卷
- 2025贵州建筑安全员-B证考试题库附答案
- 民用无人驾驶航空器产品标识要求
- 中国音乐史与名作赏析智慧树知到期末考试答案章节答案2024年山东师范大学
- 中铁集团会计核算手册
- 伤口护理小组工作总结共34张课件
- 小学科学教育科学四年级上册运动和力《运动与摩擦力》说课稿修
- 区域地质及矿区地质图清绘规程
- 10套深蓝色商务医院科室组织架构PPT图表合集
- DB44∕T 1784-2015 木本园林植物修剪技术规程
- 青年心理学第六讲(人际关系与沟通)
- 核医学科PDCA案例
- ABB断路器参数调试讲义
评论
0/150
提交评论