ImageVerifierCode 换一换
格式:DOCX , 页数:17 ,大小:21.40KB ,
资源ID:11597954      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/11597954.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(扫雷游戏实验报告1.docx)为本站会员(b****4)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

扫雷游戏实验报告1.docx

1、扫雷游戏实验报告1(此文档为word格式,下载后您可任意编辑修改!)简易版扫雷游戏实验报告一、 问题描述模仿windows扫雷游戏,开发一个简易版扫雷游戏系统。二、功能分析总体游戏过程分析:在屏幕中央位置显示一个雷区,雷区范围内预先埋设了一定数量的随机分布的地雷;玩家通过上下左右键控制光标在雷区的各个小方块之间移动并做标记;若能正确标记出雷区中的所有地雷,则游戏胜利;否则踩雷,游戏失败。简易版扫雷游戏要具备以下功能:1) 开局:首先选择游戏等级,然后生成不同等级的雷区界面。游戏等级分为三级:各等级方块数为初级:88、中级:1616、高级:2424;各级地雷数=总方块数6;雷区每个方块下面或埋藏

2、有1个地雷,或者没有地雷;2) 挖雷:将光标移到某个方块,并按空格或回车键,可挖开它;若所揭方块下有雷,则踩雷,此时所有含地雷的块都标记,该局游戏失败;如果方块上出现数字,它代表在它周围的8个方块中共有多少颗地雷;3) 标记地雷:在光标所在的某个方块上按F或f键,则标记此块下埋着地雷(实际上可能是误标),显示为F。每标记一个地雷,地雷数减少1;4) 标记疑问:在光标所在的某个方块上按Q或q键,则在某方块上面标一个问号(?),意味着没有把握判定它是否有雷。标记为?的块可在恰当的时候再按标记地雷或挖开; 5) 自动挖开:如果某个数字方块周围的地雷全都标记完,则在该方块上按A或a键,将其剩下的方块挖

3、开;6) 输入:通过键盘输入相关指示信息;7) 输出:提示游戏是否成功,是否继续。三、程序设计扫雷游戏系统的顶层层次图如下:从以下几方面“自顶向下”进一步逐步求精: 继续分析已有功能,直到精化出所有子功能,确定模块间接口; 描述精化后每个模块的处理过程; 确定主要的数据及其数据结构; 确定输入输出数据的内外部形式; 界面的设计以下是详细设计:(1)确定游戏的界面。游戏屏幕中央显示由小方块组成的雷区,小方块的背景显示为浅灰,表示该方块没有被挖开或标记;小方块的背景显示为深灰,表示它已经被挖开或标记为“F”、“?”或“*”;当选中一个方块要操作时,它的边框线为红色。在屏幕的左上方显示游戏是否成功等

4、信息,这也是游戏结果的表现形式。如图2所示。(2)决定游戏的输入方式。采用键盘,通过光标的移动来选择操作的小方块,根据所敲击的键值来选择游戏的功能。下面是对键盘功能键的定义: 上,下,左,右键用来移动光标的位置; 回车或者空格键用来挖开光标当前指向的一个方块; F, f 标记当前光标指向的方块有地雷; Q, q 在光标指向方块打一个问号,表示可能有地雷; A , a 自动挖开光标周围的方块; ESC 退出游戏。(3)确定主要的数据,这里主要是有关雷区的数据。 雷区界面数据int MAXCOL=640; *屏幕最大宽度*int MAXROW=480; *屏幕最大高度*#define _ROW 2

5、4 *雷区最多方块行数*#define _COL 24 *雷区最多方块列数*int ROW=8; *当前游戏雷区行数*int COL=8; *当前游戏雷区列数*#define SIZEX 20 *雷区方块的水平大小(像素数)*#define SIZEY 20 *雷区方块的垂直大小(像素数)*#define STARTX (MAXCOL-COL*SIZEX)2 *水平起始位置*#define STARTY (MAXROW-ROW*SIZEY)2 *垂直起始位置* 雷区内部数据int totalMine; * 整个雷区所含的地雷总数*int table_ROW_COL; * 数组table的每个元

6、素值记录了雷区对应方块是否有雷:1表示有雷,0表示没有雷*int num_ROW_COL;* 数组num的每个元素值记录了雷区对应方块周围有多少个地雷*int flag_ROW_COL;* 数组flag的每个元素值记录了雷区对应方块当前的状态*在整个系统中table_ROW_COL、num_ROW_COL、flag_ROW_COL是最核心的数据,是雷区的内部表示,游戏的挖雷、标记雷、标记疑问、自动挖开等界面操作,在内部实际上是对这些数据的操作。 方块(i,j)的状态取值:#define UNFLAG 0 * 表示该方块还没有被打开或者标记*#define FLAGED 1 * 标记该方块有地雷

7、*#define QUESTION 20 * 表示该方块可能有地雷*#define EXPLOD 30 * 踩到地雷爆炸了*#define OPEN 40 * 一个没有地雷的方块被打开* 光标当前位置数据int pi,pj; * 记录光标的当前位置,初始时光标在(0,0)上*int di8= 1,0,-1; *x方向偏移量*int dj8=,-1,-1; *y方向偏移量* 游戏状态数据int gameRes; *记录游戏结束的结果状态,值为0表示按esc键退出游戏;-1 表示游戏失败;gameRes = 1 表示游戏胜利。实际为输出数据的内部形式* 功能键的键值*为避免书写错误和明确含义,对系

8、统的按键值用符号常量来定义*上,下,左,右键*#define UP 0x4800#define DOWN 0x5000#define LEFT 0x4b00#define RIGHT 0x4d00*回车、空格键*#define ENTER 0x1c0d#define SPACE 0x3920*F, f *#define UPPERF 0x2146#define LOWERF 0x2166*Q, q*#define UPPERQ 0x1051#define LOWERQ 0x1071*A , a*#define UPPERA 0x1e41#define LOWERA 0x1e61*ESC*#de

9、fine ESC 0x011b(4)功能模块进一步求精在C系统中屏幕的输出默认的方式是文本方式,所以需要首先将显示方式设置为图形方式。简易版扫雷程序主控模块的流程如图3所示,下面从主控模块入手,继续利用逐步求精的方法来设计系统。第一步,写出主程序的基本框架,确定各子模块名字和参数。int main() initGraph(); *图形显示方式初始化*do newGame(); *初始化新游戏,即开局* int gameRes=0; do int key = getKey(); *读入操作信息* if (key = ESC) gameRes = 0;break; switch(key)对其他ke

10、y值进行判断处理; if (checkWin() *判断游戏是否胜利*gameRes = 1; while(!gameRes); while (!confirm(gameRes); return 0;主控模块的各子模块说明: void initGraph()函数:用于将显示器显示方式设置为图形方式。 void newGame()函数:开局初始化新游戏界面及数据。 int getKey()函数:得到从键盘读入的操作信息。 int checkWin()函数:用于判断游戏是否获胜。若返回值为1表示胜利,返回值为0表示游戏还没结束。 int confirm(int) 函数:用于判断游戏是否重新开始。参

11、数的值来自gameRes,gameRes=0,表示按esc键退出游戏;gameRes = -1,表示踩到地雷,游戏失败;gameRes = 1,表示游戏胜利。Confirm的返回值为0表示重新开始游戏;为1表示关闭游戏,退出程序。第二步,对“图形初始化”功能模块进一步求精。void initGraph( ) int gdriver = DETECT, gmode, errorcode; * 自动检测最高图形模式* initgraph(&gdriver, &gmode, ); *初始化图形模式* errorcode = graphresult(); * 读取初始化结果* if (errorcod

12、e != grOk) * 如果有错误发生* printf(Graphics error: %sn, grapherrormsg(errorcode); printf(Press any key to key; *若输入的是有效的功能键,就返回* 第五步,对 语句“对其他key值进行判断处理”进一步求精。 switch(key) case ENTER:case SPACE: gameRes = openMine(pi,pj); break; *打开方块* case UP: moveUp(); break; *光标上移一格* case DOWN: moveDown(); break; *光标下移一

13、格* case LEFT: moveLeft(); break; *光标左移一格* case RIGHT: moveRight(); break; *光标右移一格* case LOWERF: case UPPERF: flagBlock(pi,pj); break; *标记地雷* case LOWERA: case UPPERA: gameRes = autoOpen(pi,pj); break; *挖开地雷* case LOWERQ:case UPPERQ: questBlock(pi,pj); break; *标记疑问* default: break;这里的两个变量pi,pj表示为光标在雷

14、区中的位置。当key值为ENTER或SPACE时,执行gameRes = openMine(pi,pj)操作,函数openMine(i,j)用于挖开光标指向的方块(i,j)。参数:i表示坐标的行的值,j表示坐标的列的值。返回:整型。挖开了一个雷返回1,否则返回0。算法描述细化如下:a) 判断方块是否已经被挖开。若是返回0值,若不是,接(b)。b) 判断是否有地雷。若有,整个雷区没有挖开的且有地雷的方块的flag值置为EXPLOD,并调用drawBlock()函数重新画这些方块,然后返回-1值,表示踩到地雷。若没有地雷,接(c)。c) 将flag值置为OPEN,调用drawBlock()函数重新

15、画该方块。判断该方块的num值,若值为0,递归调用openMine函数挖该方块周围的八个方块,num值不为0时,返回0值,表示成功挖开该方块。当key值为UP、DOWN、LEFT或RIGHT时,分别执行moveUp()、moveDown()、moveLeft()或moveRight()操作。函数moveUp(),将当前光标(pi,pj)上移一格操作。其实现过程为:判断边界条件pi0,然后调用drawBlock()函数重新画光标原来所指的方块和现在所指的方块。其余函数的实现类似,要注意边界条件的判断。函数moveDown(),当前光标(pi,pj)下移一格操作;函数moveLeft(),当前光标

16、(pi,pj)左移一格操作; 函数moveRight(),当前光标(pi,pj)右移一格操作。当key值为LOWERF或UPPERF时,执行flagBlock(pi,pj)操作。函数flagBlock(i, j)标记光标所指的方块(i,j)有地雷。函数实现过程如下:如果方块的flag值为FLAGED,则将flag值设为UNFLAG;如果方块的flag值为UNFLAG,则将flag值设为FLAGED。接着调用drawBlock()函数重新画这个方块。当key值为LOWERA或UPPERA时,执行gameRes= autoOpen(pi,pj)操作。函数autoOpen(i, j)表示如果某个已经

17、打开了的小方块显示的数字等于它周围已经被标记为雷的小方块的数目,则表明周围没有被挖开的小方块都已经不是地雷的,自动挖开这些小方块。参数: i 表示坐标的行的值,j表示坐标的列的值。返回:整型。自动挖开的过程中由于玩家的标记有错误导致挖开了一个雷使得游戏失败,返回1,否则返回0。函数实现过程如下:a) 判断当前的方块是否被挖开。若没有,自动挖开无效,返回0;若是,接(b)。b) 计算当前方块周围被标记为FLAGED的方块数目。若该数目等于当前方块的numij值,对(i,j)小方块的八个邻居中所有没有被挖开的小方块调用openMine函数。如果自动挖开过程中踩到地雷,返回1;否则,返回0值。当ke

18、y值为LOWERQ或UPPERQ时,执行questBlock(pi,pj)操作。函数questBlock(i, j)在光标所指向的方块(i,j)上打一个问号,表示可能有地雷。函数实现过程:如果方块的flag值为QUESTION,则将flag值设为UNFLAG;如果方块的flag值为UNFLAG,则将flag值设为QUESTION。接着调用drawBlock()函数重新画这个方块。第六步,对“判断游戏是否胜利”功能模块进一步求精。int checkWin()功能:判断当前玩家是否已经取胜(即所有没有雷的坐标都已经被挖开了)。参数:无返回值: 整型值,1表示玩家取得了胜利,0表示没有。算法描述:对

19、每个没有地雷的坐标,判断该坐标是否已经被挖开,如果遇到有一个没有挖开,返回0;相反,如果所有没有地雷的坐标都已经被挖开返回1。第七步,对“判断游戏是否重新开始”功能模块进一步求精。int confirm(int res)功能:判断当前玩家是否还要重新开始新的游戏。参数:游戏结束的状态:0-ESC退出,-1-失败,1-胜利返回值: 整型值,1表示继续,0表示结束游戏。算法描述:首先在屏幕左上角位置显示当前的游戏结束状态,提示是否继续游戏;然后等待玩家从键盘输入键值:若输入Y或y,则返回1继续游戏;若输入N或n,则返回0结束游戏。四、编码扫雷游戏的源程序分为三个文件:main.c、miner.c和

20、key.c,其中main.c的内容为主控程序,key.c中包含获取输入信息的函数以及功能键的键值,miner.c中将初始化部分、界面绘制的部分、信息处理部分以及相关的数据集中在一起。*文件main.c*#include key.c#include miner.cint main() int gameRes; *记录游戏结束的结果状态:0表示退出游戏;-1游戏失败; 1为胜利。* initGraph(); *初始化图形显示方式* do newGame(); *初始化新的游戏* gameRes=0; do *主循环处理按键信息* int key = getKey(); *读入操作信息* if(ke

21、y = ESC) break; switch(key) *对其他有效操作的处理* case ENTER: case SPACE: gameRes = openMine(pi,pj);break; case UP: moveUp();break; case DOWN: moveDown();break; case LEFT: moveLeft();break; case RIGHT: moveRight();break; case LOWERF: case UPPERF: flagBlock(pi,pj);break; case LOWERA: case UPPERA: gameRes = au

22、toOpen(pi,pj);break; case LOWERQ:case UPPERQ: questBlock(pi,pj);break; if(checkWin() gameRes = 1; while(!gameRes); while (!confirm(gameRes) ; return 0;*- 文件main.c结束-*文件key.c*#include bios. key; *-文件 key.c结束-*文件miner.c*#include graphics., grapherrormsg(errorcode); printf(Press any key to 0;*初始化游戏*voi

23、d newGame() cleardevice(); setGrade(); cleardevice(); generateMine(); pi = pj = 0; drawTable();*判断游戏是否胜利*int checkWin() int i,j; for(i=0;iROW;i+) for(j=0;j0) pi-; drawBlock(pi,pj); drawBlock(pi+1,pj); *光标下移一格*void moveDown() if(pi0) pj-; drawBlock(pi,pj); drawBlock(pi,pj+1); *光标右移一格*void moveRight()

24、 if(pjCOL-1) pj+; drawBlock(pi,pj); drawBlock(pi,pj-1); *标记有雷*void flagBlock(int i,int j) if(flagij = FLAGED) flagij = UNFLAG; else if(flagij = UNFLAG) flagij = FLAGED; drawBlock(i,j);*标记不确定*void questBlock(int i,int j) if(flagij = QUESTION) flagij = UNFLAG; else if(flagij = UNFLAG) flagij = QUESTIO

25、N; drawBlock(i,j);*挖雷*int openMine(int i,int j) int ii,jj,k; if(flagij = OPEN) return 0; if(tableij) *meet a mine* for(ii=0;iiROW;ii+) for(jj=0;jjCOL;jj+) if(tableiijj & flagiijj = UNFLAG) flagiijj = EXPLOD; drawBlock(ii,jj); return -1; *游戏失败* else flagij = OPEN; drawBlock(i,j); if(numij=0) for(k=0;

26、k=0 & ni=0 & njCOL) openMine(ni,nj); return 0; *自动挖开*int autoOpen(int i,int j) int k,c=0; int ni,nj; int ret=0; if(! (flagij = OPEN) return 0; for(k=0;k=0 & ni=0 & njCOL) if(flagninj = FLAGED) c+; if(c = numij) for(k=0;k=0 & ni=0 & njCOL) if(flagninj = UNFLAG) if(openMine(ni,nj) = -1) ret = -1; return ret;*-文件miner.c结束-*

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1