扫雷课程设计报告

上传人:Sc****h 文档编号:138239977 上传时间:2022-08-20 格式:DOC 页数:20 大小:749KB
返回 下载 相关 举报
扫雷课程设计报告_第1页
第1页 / 共20页
扫雷课程设计报告_第2页
第2页 / 共20页
扫雷课程设计报告_第3页
第3页 / 共20页
点击查看更多>>
资源描述
下载可编辑Har b in In sti tu te o f Techn o log y课程设计报告课程名称 : 数据结构与算法课程设计设计题目 : 扫雷院系: 计算机科学与技术学院班级: 10503104设计者:陆亮学号: 1050310404指导教师 : 刘晓燕设计时间 : 2007-8-27 到 2007-9-8哈尔滨工业大学.专业 .整理 .下载可编辑哈尔滨工业大学课程设计任务书姓名:陆亮院 (系): 计算机科学与技术学院专业:计算机科学与技术班号: 1050310404任务起至日期 :2007 年 8 月 27 日至 2007 年 9 月 9 日课程设计题目 : 扫雷游戏课程设计要求 : 能够给出游戏结果(输、赢、剩余的雷数 、用掉的时间按妙计)。 游戏界面最好图形化,否则一定要清楚的字符界面。设计任务总述 :本题目做一个Nx M的扫雷游戏,每个方格包含两种状态: 关闭 ( closed ) 和打开( opened ), 初始化时每个方格都是关闭的,一个打开的方格也会包含两种状态:一个数字( clue )和一个雷 ( bomb )。 你可以打开 ( open )一个方格 ,如果你打开的是一个bomb ,那么就失败 ;否则就会打开一个数字,该数字是位于0, 8 的一个整数 ,该数字表示其所有邻居方格 ( neighboring squares)所包含的雷数,应用该信息可以帮助你扫雷。.专业 .整理 .下载可编辑工作计划及安排:8 月 27 日 -8 月 30 日:学习 vc+6.0 的 MFC 编程,以及扫雷所需设计的算法;8 月 31 日-9 月 5 日:实现扫雷的基本框架 ;9月 6日-9 月9日:优化功能;指导教师签字 _年月日数据结构与算法课程设计中期检查结果指导老学号 :1050310404姓名 :陆亮刘晓燕师:课程设计题目:扫雷系统总任务描述:本题目做一个Nx M 的扫雷游戏 ,每个方格包含两种状态: 关闭 ( closed )和打开( opened ),初始化时每个方格都是关闭的,一个打开的方格也会包含两种状态:一个数字( clue )和一个雷 ( bomb )。 你可以打开( open )一个方格 ,如果你打开的是一个bomb ,那么就失败 ;否则就会打开一个数字,该数字是位于 0 , 8的一个整数 ,该数字表.专业 .整理 .下载可编辑示其所有邻居方格( neighboring squares)所包含的雷数 ,应用该信息可以帮助你扫雷。已完成工作描述:1.所需的算法都已经设计完毕,包括展拓空白区域,判胜,获得周围雷数,以及随机布雷2.翻阅了大量有关的书籍,初步学习了VC+6下一步工作计划及安排 :1 星期一 星期二 :鼠标左右键的处理流程;2 星期三 :计时器功能 ,计数功能 ;3星期四:调试,完善;4. 星期五 :准备 PPT 答辩指导教师签填表时间 :2007-9-3字:一、 题目分析(1) 问题描述本题目做一个 N x M 的扫雷游戏 ,每个方格包含两种状态 :关闭(closed )和.专业 .整理 .下载可编辑打开( opened ),初始化时每个方格都是关闭的,一个打开的方格也会包含两种状态 :一个数字 ( clue )和一个雷 ( bomb )。你可以打开 ( open )一个方格,如果你打开的是一个 bomb ,那么就失败 ;否则就会打开一个数字 ,该数字是位于 0 , 8 的一个整数 ,该数字表示其所有邻居方格 ( neighboringsquares )所包含的雷数 ,应用该信息可以帮助你扫雷。图 4-20扫雷游戏的图例具体实现要求的细节 :a.能够打开一个方格 ,一个已打开的方格不能再关闭。b.能够标记一个方格,标记方格的含义是对该方格有雷的预测(并不表示真的一定有雷 ),当一个方格标记后该方格不能被打开,只能执行取消标记的操作,只能在取消后才能打开一个方格。c.合理分配各个操作的按键,以及各方格各种状态如何合理显示。(2) 基本要求a.能够给出游戏结果 (输、赢、剩余的雷数 、用掉的时间按妙计 )。b.游戏界面最好图形化 。(3)所需解决的问题.专业 .整理 .下载可编辑a.运行的结果必须采用可视化的界面,因此开发工具我选择了VC+6.0 ,用MFC 工程解决此题目 ;b.题目要求 M*N 的雷区,因此学要与用户对话 ,以获得区域大小和雷数目,可以使用 MFC 中的对话框来实现 ;c.雷的位置应该是随机的,因此必须采用生成随机数的办法布雷,同时还应该注意避免用户第一次就点击到了雷,这是没有意义的 ;d.方格会处于各种不同的状态,设计其结构并定义相应的状态宏是必要的;e.因游戏的状态不同,消息机制是会对鼠标信息进行不同处理,因此要定义游戏状态宏 ,并时时记录游戏的状态 ;f.点击到了某区域发现其周围没有雷,那么显而易见应该点开周围的区域,如果这样的操作由用户一一完成,将增加用户很多的操作负担,大大减少了游戏的趣味性 ,因此周围的空白区域应该自动打开,这就需要一个函数来递归的完成此任务;g.为了获得所点击的方格周围雷数,要设计一个函数 ,其中要注意处理边界方格;h.当鼠标左或右键点击后 ,都应该判断是否胜利 ,胜利条件应当选择准确 ;i.左右键点击后 ,响应其消息的函数是相当复杂的,应当根据点击的位置 ,游戏的状态以及点击的方格状态,来进行不同的处理 ;j.确定点击的是哪一个方格,可以用点击的位置坐标来计算;k.设计一个计时器 ,显示游戏进行的时间 ;l.设计一个计数器 ,显示剩余的雷数 ,考虑标记的雷数比实际的雷数多时的情况二、 总体设计.专业 .整理 .下载可编辑1.要实现点击后出现不同的图像,如空白或标记为雷或标记为有2 两颗雷等 ,就需要利用 MFC 的重绘机制 。重绘的依据是方块的属性,重绘的时间是在以下三个动作结束之后 :左键点击 ,右键点击 ,以及重置游戏 。 下面就分别介绍这三个动作要进行什么样的处理,为重绘做好准备 。(1).左键点击左键点击后判断位置点击位置雷区笑脸区等待状态进行状态结束状态重置游戏下面重点分析点 击在雷区 后的处理m_poldmine = GetMine(point.x, point.y) /通过坐标获取方块位置/ 如果游戏处于等待状态if(GameState =GS_WAIT)/ 启动计时器 ;SetTimer();/ 布雷;LayMine();.专业 .整理 .下载可编辑/ 改变游戏状态为运行 ;GameState = GS_RUN;/ 如果游戏处于进行状态if(GameState = GS_RUN)/ 方块状态为正常时进行处理 ,对于已经点开的区域不再处理If(方块属性为正常 )If( IsMine()/ 所点击的方格是雷则要进行失败处理Dead();else/ 不是雷的处理around = GetAroundnum();/获取其周围雷的数目if(around = 0)/如果周围没雷ExpandMines();/ 展拓空白区域else/ 如果周围有雷DrawDownNum();/改变此方块属性if(victory() /判断是否胜利胜利处理 ;.专业 .整理 .下载可编辑Invalidate();/ 发出重绘消息 ;(2).右键点击void CLuliangView:OnRButtonDown(UINT nFlags, CPoint point)/ 游戏处于进行状态是响应右键的条件 ,右键只能在雷区起作用if(GameState = GS_RUN & point.y 80)NewMine = GetMine(point.x, point.y);/获得点击方块switch( NewMine-uState)/ 根据方块的属性做不同标记/ 正常状态的标记为雷 ,剩余雷数减 1 case STATE_NORMAL:NewMine-uState = STATE_FLAG; m_LeftMineNum-;break;/ 被标记为雷的改为未知状态 ,剩余雷数加 1 case STATE_FLAG:NewMine-uState = STATE_DICEY; m_LeftMineNum+;break;/ 被标记为未知状态的改为正常状态.专业 .整理 .下载可编辑caseSTATE_DICEY:NewMine-uState = STATE_NORMAL;break;default: break;/其他状态的方格 ,右键均不处理if(Victory()/判断是否胜利胜利处理 Invalidate();/ 发出重绘消息 ;(3).重新设置游戏 ,即改变雷数和雷区大小SetMineArea sizedlg;/ 建立对话框对象sizedlg.DoModal();/ 弹出对话框XMineNum = sizedlg.m_x_mine_num;/获得雷区宽YMineNum = sizedlg.m_y_mine_num;/获得雷区高MineNum = sizedlg.m_MineNum/ 获得雷的个数 ;SizeWindow();/ 改变窗口大小InitialGame();/ 初始化方格 ,计时器,计数器等Invalidate();/ 发出重绘消息 ;2.还有一个十分重要的函数就是绘制函数OnDraw (),每次重绘时都会自动调用此函数 。 它绘制了雷区 ,计数器区 ,计时器区以及笑脸区。下面是它所绘制的大体框架 :.专业 .整理 .下载可编辑三、 数据结构设计雷区方格的数据结构( 1)为了唯一标识一个方格 ,设计两个 UINT(无符号整数 )变量来记录它的行和列;( 2)每一个方格有两种属性 ,雷与非雷 ,因此需要一个 BOOL 变量记录其属性;( 3)每个方格都有一个状态 ,比如未被点击过的状态 ,被标记为雷的状态 ,打开后周围有一颗雷的状态等等。标志状态有两个作用 :a.其状态的不同决定了将其绘制为什么样的图形,比如某方格其状态为“未被点击过 ”,那么它会被绘制为;某方格状态为 “被标记为雷 ”,那么它.专业 .整理 .下载可编辑被绘制为;又如某方格状态为 “打开后显示 1”,被绘制为。b.其状态的不同决定了它被点击后受到不同的处理 。 比如方格 1的状态为“未被点击过 ”,方格 2 的状态为 “打开后显示 1”,当鼠标左键点击方格 1的时候,它将会被打开判断是否是雷等操作 ,而当鼠标点击方格2的时候,它不会被做任何处理 ;四、 算法设计(1)布雷函数 :利用 srand(),rand() 随机机制产生随机数 ,分别对列和行取模 ,便产生了雷的随机位置 。 但是布雷前 ,先要判断此随机位置是否已经布上了雷。(2 )获得周围雷的数目扫描其周围的所有相邻方格,记录雷数 ,扫描前要选择合理的起始点,以处理边框上的特殊位置 。处理方法是 :如果方块处在第0 行,扫描起始行为 0,否则不变 ;如果方块处在第0 列,扫描起始列为 0,否则不变 ;(3 )展拓空白区域展拓原因 :当玩家点击的方块周围无雷时,此方块会被重绘为空白,此时没有必要让玩家将其周围一一点开,应直接打开展拓条件 :周围雷数为零函数 void ExpandMines(UINT row, UINT col)参数:row, col 所点击的方块位置.专业 .整理 .下载可编辑算法 :递归递归结束条件 :某一个方块不需要拓展就是因为其周围的雷数不是零(4)判断胜利两个条件 :1.属性不为雷 ( ATTRIB_EMPTY)的方块当前状态在STATE_NUM1 和 STATE_EMPTY之间(19 )2.属性为雷 ( ATTRIB_MINE) 的方块当前状态为STATE_MINE五、 物理实现及结果1. 主要数据结构的物理设计( 1)雷区方格的数据结构方块的的结构体typedef structUINT uRow;/ 所在雷区二维数组的行UINT uCol;/ 所在雷区二位数组的列UINT uState;/ 当前状态UINT uAttrib;/方块属性 (雷或非雷 ) MINEWND;当前状态宏 :#define STATE_NORMAL0/ 正常.专业 .整理 .下载可编辑#define STATE_NUM11/周围有 1雷#define STATE_NUM22#define STATE_NUM33#define STATE_NUM44#define STATE_NUM55#define STATE_NUM66#define STATE_NUM77#define STATE_NUM88#define STATE_EMPTY9#define STATE_FLAG10/ 被右键标记为雷#define STATE_MINE11/ 当失败时把所有的雷标记出#define STATE_ERROR12/ 被右键误标记为雷#define STATE_ERRORCLICK13/ 被左键点击为雷#define STATE_DICEY14/ 未知状态(2)游戏状态#defineGS_WAIT1/#define GS_RUN2/#defineGS_FAIL3/#defineGS_WIN4/用 GameState 变量记录游戏的状态 ,初始化为 GS_WAIT2. 核心算法的物理实现( 1)布雷函数 :.专业 .整理 .下载可编辑当鼠标第一次点击雷区时布雷void CMineWnd:LayMines(UINT row, UINT col)srand( (unsigned)time( NULL ) ); /埋下随机种子UINT i, j;for(UINT index = 0; index m_uMineNum;)i = rand() % m_uYNum; /取随即数j = rand() % m_uXNum;/ 保证第一次点击的不是雷if (i = row & j = col) continue;if(m_pMinesij.uAttrib != ATTRIB_MINE)m_pMinesij.uAttrib = ATTRIB_MINE;/雷index+;(2 )获得周围雷的数目函数 :难点是四个顶点和四边上特殊的方块UINT GetAroundNum(UINT row, UINT col).专业 .整理 .下载可编辑/ 寻找合适的起始位置UINT i, j;UINT minRow = (row = 0) ? 0 : row - 1;UINT maxRow = row + 2;UINT minCol = (col = 0) ? 0 : col - 1;UINT maxCol = col + 2;/ 通过方块的属性 ( uAttrib )来判断是否是雷UINT around;for (i = 10; i 10; i+)for (j = minCol; j maxCol; j+)if (!IsInMineArea(i, j)continue;if (m_pMinesij.uAttrib = ATTRIB_MINE)around+;return around;.专业 .整理 .下载可编辑( 3 )展拓空白区域void ExpandMines(UINT row, UINT col)判断起始点minRow,maxRow,minCol,maxCol;around = GetAroundNum(row,col);/ 获得雷的数目if(around != 0) /递归结束条件其属性标记为相应数字;elsefor (其周围所有的方块)ExpandMines();( 4)判断胜利int Victory()for(UINT i = 0; i XMineNum; i+)for(UINT j = 0; j YMineNum; j+)if(m_pMinesij.uAttrib = ATTRIB_EMPTY)if(m_pMinesij.uStateSTATE_EMPTY).专业 .整理 .下载可编辑return 0;elseif(m_pMinesij.uState != STATE_FLAG)return 0;return 1;3. 实现结果( 1)游戏处于等待状态(2 )游戏处于进行状态( 3)游戏胜利(4)游戏失败.专业 .整理 .下载可编辑六、结果分析程序完成了题目的所有要求,并且参照微软游戏加入了右键标记为未知状态的功能,但是有两点不足 :1.当改变雷区大小时 ,窗口不能自动跟随改变 ,必须手动将窗口拉大 ;2.由于重绘面积很大 ,因此宽口的闪烁现象较为明显;七、结论1.对数据结构在应用程序中起到的强大支持作用有了深刻认识,体会到了数据结构思想的重要性 。2.通过本次课程设计 ,我初步了解了MFC 的运行机制以及基本的框架,初步掌握了可视化窗口的编程方法,也对图形处理有了一定的了解,收获很大 。八、附录无九、参考文献1.Visual C+教程(机械工业出版社,郑阿奇主编 ).专业 .整理 .下载可编辑2.Visual C+经典游戏程序设计(人民邮电出版社, 罗伟坚编著 )3.Visual C+6.0教程 (电子工业出版社,刘文智等编著)4.Visual C+6.0编程宝典 (电子工业出版社, David Simon【美】,周瑜萍等编著).专业 .整理 .
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 图纸专区 > 幼儿教育


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!