版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
-------z--z- C语言程序设计报告题目:扫雷游戏班级:网101组长:~~成员:~~,~~日期:2011.9-2011.11目录四函数说明游戏控制部分图形处理部分鼠标处理部分五调试与测试六附录
P.3p.4p.5p.7p.10p.11p.12p.15一基本情况开发平台:win-tc(windows-xp)开发进度:9.10~9.20 小组进行图形处理及鼠标相关资料收集,掌握相关形处理及鼠标相关技术9.21~10.10 小组成员讨论程序实现算法及任务分配10.10~11.3 代码实现,调试任务划分: 超负责程序总体设计,游戏控制部分实现,后期调试艳负责程序图形处理及鼠标处理部分实现,总结文档编写二游戏规则玩家进入游戏界面后,只能通过鼠标进行操作,一旦有键盘输入,则退出游戏程序。游戏框图左上方显示的数字为此局游戏中包含的地雷数目。中间黄色笑脸为重新开始按钮,一旦鼠标左键单击此位置,则退出正在进行的扫雷游戏,游戏重新开始。游戏中包含10*10个空格,可以通过鼠标左键单击或者右键单击来进行扫雷游戏。鼠标单击表示打开此空格位置,若此位置为地雷,则输出所有的地雷分布,玩家输,游戏结束,等待玩家的选择退出或者继续开始下一次游戏。若此位置已经被左单击过,则再次进行鼠标左键单击时,游戏不做任何响应。单击过后若此位置无雷则显示空格或者数字。空格表示此处无雷,数字表示此处无雷且周围八个格子中的地雷数目为空格中的数字数目,若某个空格周围亦没有地雷分布则继续以每个方格为中心继续判断无雷就展开,显示数字或者空格,直至遇到地雷或者是边界。鼠标右键单击表示游戏玩家标识此位置为地雷,若游戏玩家在某位置右键单击过之后,再次右键单击此位置,则表示取消此处标注的地雷标志,若在此处鼠标左键单击,不做任何响应。游戏玩家依次对每一个空格,当游戏玩家把所有的非雷区域全部处理完毕,则游戏结束,玩家胜利,输出“YOUWIN”,等待玩家进一步选择。三设计思路扫雷程序主要用了一个10行10列的二维数组,数组的每个元素都是结构体类型,结构体中的num代表格当前处于什么状态,值1表示有雷,值0表示roundnum是鼠标右键的标志,如果鼠标左键单击此方格,则对应的二维数组结构体里的flag为1表示格子显示红旗,这样鼠标左键点击在这个格子上无效。首先通过生成随机数的方式布置地雷,如果在该点生成的随机数为1,则该点存在地雷,将NUM(结构体)标为1,随机数为其它值NUM(结构体)标为0,每生成一个地雷,则全局变量minenum自增一。在程序一开始统计好每个格子周围有多少地雷,将统计的结果存放在对应的结构体变量roundnum,然后当鼠标左键点击在没有地雷的格子上时进行两种方法同样判断周围的8数。在递归判断8个格子时,如果格子上有雷或者格子已经显示过雷数或者空白,以及格子上有红旗标志的话,就不再对格子进行任何判断。否则,当此处无雷,即展开此处,并且以此位置为中心继续进行递归,直至遇到边界或者地雷,跳出递归。当游戏玩家每处理一个非雷区域的格子,则对应的统计非雷方格数目的变量自减一,当该变量的值自减为0时,则表示游戏结束,该玩家胜利。具体函数流程图如下:-------z--z--------z--z-四函数说明1游戏控制部分主函数定义使用到的常数,全局变量,函数原型说明。然后初始化图形系统,调用游戏控制函数,按任意键结束游戏,关闭图形系统,游戏结束。voidSpreadMine(int 通过函数srand((int)time(0));生成随机数,随后在二重循环里,生成随机数,若生成的随机数为1,则将num(结构体)标为1,表示改点有雷,并在outtextxy(210,70,randminenum);在70)点输出雷的总数,用一百减去总雷数表示该次无雷空格的总数(在输赢判断中,若所有无雷区域都已经得到了处理,即玩家胜利。void如果单击了地雷,则地雷爆炸,游戏结束,显示地雷分布,两重循环判断每个格子的状态,如果状态值为1,则为地雷,设置红色背景,实体填充模式,画圆表示地雷。void如果所有的非雷区域的格子都处理过,就表示游戏玩家胜利,输出youwin信息。void这个函数完成初始界面的设计以及调用函数 voidSpreadMine(int t)生成地雷初始界面的主要工作是确定图的位置和方格显示的位置外边框的左上角19060右上角坐标(390290显示笑脸和地雷数的区域60)(390,90,每个方格的宽度和高度均为16.voidShowWhite(inti,int当单击某个格子,该格子周围的地雷数为0时,应该继续判断它周围8个方向的格子的周围的雷数是否为0,将这些格子都用空白显示。具体实现如下:ab空白格子数减一(统计处理过多少格子。c如果周围的地雷数为态值num置0,表示处理过;如果周围地雷数不为0,将它的状态值num置0,表示处理过,返回。voidControl()GameBegain()显示游戏初始化界面,调用GamePlay()戏;一是玩完,要么失败,要么胜利。如果是前者,则重新开始游戏。如果是后者,则判断是否单击了笑脸,是则重新开始,否则结束程序。voidGamePlay() 戏控制游戏过程主要是对鼠标按键的处理,集体算法实现如下:a.如果单击了鼠标左键则判断如果单击了笑脸,则游戏重新开始‘80ShowWhite0,子吗,则游戏胜利,显示胜利信息。b.如果单击鼠标右键,该格子没有红旗则显示红旗。如果有红旗,再击右键,则红旗消失。c重复步骤b直到按键结束游戏I.intMineStatistics(inti,intj)统计每个格子周围的地雷数,分别考虑各自处于四个角,四条边以及中间某个位置的情况。周围是上,下,左,右,左上,左下,右上,右下。在统计四个角格子周围的地雷数目时,统计其周围的三个方格是否有地雷,如统计左i+j+(设该位置坐标为)。而统计四条边上某一空格周围的地雷(i-1,(i-1,j+(,j+,(i+1,j),(i+1,j+1)(设该位置坐标为(i,j)。而统计普通位置时要统计其周围(i-1j-1(i-1(i-1,j+(,j-1(,j+1(i+,j-(i+,j-1(i+,(i+1,j+1).统计完成后,将统计结果存入对应的结构体的roundnum变量中去。图形处理部分voidInit() 对计算机进行图形模式初始化,加载图形驱动包voidDrawSmile() 画一个笑脸voidDrawRedFlag(inti,intj) 画一个红旗voidDrawEmpty(inti,intj,intmode,intcolor) 画两种空格voidClose() 关闭图形模式------鼠标处理部分voidMouseOn() 鼠标显示voidMouseOff() 鼠标隐藏voidMouseSetXY(intx,inty) 设置鼠标当前位置intLeftPress() 鼠标左键按下intRightPress() 鼠标右键按下voidMouseGetXY() 得到鼠标当前位置- z --------z--z-五调试与测试书写标识符时,忽略了大小写字母的区别编译程序把i和I认为是两个不同的变量名,而显示出错信息。C小写表示,以增加可读性。在程序嵌套比较多时,容易出错在程序嵌套比较多时,很容易多卸{{于同一条线上,这样就能够减少上述错误的出线win7不支持C语言图形全屏模式,图形处理须加载图形驱动在进行图形部分处理时win7不支持cXP也没确运行。原因是C语言在进行图形处理必须正确设置图形驱动器和模式,通过函数detectgraphics能自动进行计算机硬件检测,后再进行初始华即可。布雷随机数生成的错误以及优化在进行布雷函数编写时,首先用随机数生成函数使随机数生成围在(0-1)2可以调节就是得雷区均匀的同时,可以通过调节t5在调用递归函数及递归函数编写时的错误在调用递归函数前应该先调用MineStatistics函数统计该格子周围是否无雷,只有当该格子无雷且周围无雷时(而不时该格子处无雷即可,才能调用递归函MineStatistics函数MineStatistics输赢判断是靠检索非雷的格子是否处理完(即标红旗,二是检索非雷的格子是否已经全部处理完全。雷的数目虽然较少,但flag进行方法二的实现只需要每处理一个非雷的格子,让统计非雷数目的数据自减一,当其自减为0比较容易实现该函数鼠标的光标没法显示出来该函数鼠标的光标没法显示出来,在查询了有关鼠标光标显示后,进行了用原来的图形信息通过图形输出覆盖掉鼠标光标显示留下的痕迹还原原有图形,六附录#include<stdlib.h>#include<time.h>#include<graphics.h>#include<dos.h>#defineLEFTPRESS0xff01#defineLEFTCLICK0xff10#defineLEFTDRAG 0xff19#defineMOUSEMOVEvoidInit();voidClose();voidDrawSmile();voidDrawRedFlag(inti,intj);voidDrawEmpty(inti,intj,intmode,intcolor);voidControl();int MineStatistics(inti,intvoidSpreadMine(intt);voidShowWhite(inti,intj);voidGamePlay();voidvoidGameWin();voidGameOver();voidMouseOn();voidMouseOff();voidMouseSetXY(intx,intint LeftPress();int RightPress();voidcharrandminenum[3];intminenum;intMouseX,MouseY;intgameAgain=0;intgamePlay=0;struct{intnum;introundnum;周围九个方格的雷数*/intflag;0*/}Mine[10][10];main(){Init();Control();Close();getch();}
/*无雷标0,有雷标1*//*此位置有雷标0,否则统计/*标记为雷时为1,没有标记为voidMouseOn() /*鼠标光标显示*/{_AX=0x01;geninterrupt(0x33);}voidMouseOff() /*鼠标光标隐藏*/{_AX=0x02;geninterrupt(0x33);}voidMouseSetXY(intx,inty) /*设置鼠标当前位置*/{_CX=x;_DX=y;_AX=0x04;geninterrupt(0x33);}intLeftPress() /*鼠标左键按下*/{_AX=0x03;geninterrupt(0x33);return(_BX&1);}intRightPress(){_AX=0x03;geninterrupt(0x33);return(_BX&2);}voidMouseGetXY(){_AX=0x03;geninterrupt(0x33);MouseX=_CX;MouseY=_DX;}voidInit(){
/*鼠标右键按下*//*得到当前位置*//*图形初始化*/intgdriver,gmode;registerbgidriver(EGAVGA_driver); /*加载图形驱动包*/detectgraph(&gdriver,&gmode); /*检测硬件确定图形驱动程序模式*/initgraph(&gdriver, &gmode, ""); /*初始化图形系统,gdriver gmode分别表示图形驱动器和模式,""为图形驱动的路径*/}voidDrawSmile() /*花笑脸*/{setfillstyle(SOLID_FILL,YELLOW); /*面所画图形的填充,此处表示对下面椭圆的填充*/fillellipse(290,75,10,10); /*标,后面依次为一个宽度和一个高度*/setcolor(YELLOW); /*设置画笔颜色*/setfillstyle(SOLID_FILL,BLACK); /*此处表示对下面两个椭圆的填*/fillellipse(285,75,2,2);fillellipse(295,75,2,2);setcolor(BLACK);bar(287,80,293,81); /*画一个二维线条*/}voidDrawRedFlag(inti,intj){setcolor(7); /*设置画笔颜色setfillstyle(SOLID_FILL,RED);bar(198+j*20,95+i*20,198+j*20+5,95+i*20+5);setcolor(BLACK);line(198+j*20,95+20*i,198+j*20,95+i*20+5);}voidDrawEmpty(inti,intj,intmode,intcolor){setcolor(color);setfillstyle(SOLID_FILL,color);if(mode==0) /*没有单击过显示大格子bar(200+j*20-8,100+i*20-8,200+j*20+8,100+i*20+8);if(mode==1) /*单击过后显示小格子bar(200+j*20-7,100+i*20-7,200+j*20+7,100+i*20+7);}voidClose(){closegraph();}voidSpreadMine(intt){inti,j;minenum=0;for(j=0;j<10;j++){Mine[i][j].num=rand()%t;srand((int)time(0)); /*生成时间种子for(j=0;j<10;j++){Mine[i][j].num=rand()%t;if(Mine[i][j].num==1)minenum++;elseMine[i][j].num=2;Mine[i][j].flag=0;}sprintf(randminenum,"%d",minenum);setcolor(1);settextstyle(0,0,2);outtextxy(210,70,randminenum);minenum=100-minenum; /*变量取空白格数量MouseOn();}voidGameOver(){inti,j;setcolor(0);for(i=0;i<10;i++)for(j=0;j<10;j++)if(Mine[i][j].num==1){DrawEmpty(i,j,0,RED);setfillstyle(SOLID_FILL,BLACK);fillellipse(200+j*20,100+i*20,7,7);}}voidGameWin(){setcolor(1);settextstyle(0,0,2);outtextxy(230,30,"YouWin");}intMineStatistics(inti,intj){intnNUM=0;if(i==0&&j==0) /*统计左上角*/{if(Mine[0][1].num==1)nNUM++;if(Mine[1][0].num==1)nNUM++;if(Mine[1][1].num==1)nNUM++;if(Mine[1][1].num==1)nNUM++;}elseif(i==0&&j==9) /*统计右上角*/{if(Mine[0][8].num==1)nNUM++;if(Mine[1][9].num==1)nNUM++;if(Mine[1][8].num==1)nNUM++;}elseif(i==9&&j==0) /*统计左下角*/{if(Mine[9][1].num==1)nNUM++;if(Mine[8][0].num==1)nNUM++;if(Mine[8][1].num==1)nNUM++;}elseif(i==9&&j==9){if(Mine[9][8].num==1)nNUM++;if(Mine[8][9].num==1)nNUM++;if(Mine[8][8].num==1)nNUM++;}elseif(i==0&&j!=0&&j!=9){
/*统计右下角*//*统计第一行*/if(Mine[i][j+1].num==1)nNUM++;if(Mine[i][j-1].num==1)nNUM++;if(Mine[i+1][j-1].num==1)nNUM++;if(Mine[i+1][j].num==1)nNUM++;if(Mine[i+1][j+1].num==1)nNUM++;if(Mine[i+1][j+1].num==1)nNUM++;elseif(i==9&&j!=0&&j!=9) /*统计最后一行*/{if(Mine[i][j+1].num==1)nNUM++;if(Mine[i][j-1].num==1)nNUM++;if(Mine[i-1][j-1].num==1)nNUM++;if(Mine[i-1][j].num==1)nNUM++;if(Mine[i-1][j+1].num==1)nNUM++;}elseif(j==0&&i!=0&&i!=9) /*统计第一列*/{if(Mine[i-1][j].num==1)nNUM++;if(Mine[i+1][j].num==1)nNUM++;if(Mine[i][j+1].num==1)nNUM++;if(Mine[i-1][j+1].num==1)nNUM++;if(Mine[i+1][j+1].num==1)nNUM++;}elseif(j==9&&i!=0&&i!=9) /*统计最后一列*/{if(Mine[i-1][j].num==1)nNUM++;if(Mine[i+1][j].num==1)nNUM++;if(Mine[i][j-1].num==1)nNUM++;if(Mine[i-1][j-1].num==1)nNUM++;if(Mine[i+1][j-1].num==1)nNUM++;}else{if(Mine[i-1][j-1].num==1)nNUM++;if(Mine[i-1][j].num==1)nNUM++;if(Mine[i-1][j+1].num==1)nNUM++;if(Mine[i][j-1].num==1)nNUM++;if(Mine[i][j+1].num==1)nNUM++;if(Mine[i+1][j-1].num==1)nNUM++;if(Mine[i+1][j].num==1)nNUM++;if(Mine[i+1][j+1].num==1)nNUM++;}return(nNUM);}voidGameBegain(){inti,j;cleardevice();if(gamePlay!=1){MouseSetXY(290,70); /*鼠标开始位置,并作为初时坐标*/MouseX=290;MouseY=70;}gamePlay=1; /*下次开始鼠标不重新初始化*/minenum=0;setfillstyle(SOLID_FILL,7);bar(190,60,390,290);for(i=0;i<10;i++)for(j=0;j<10;j++)DrawEmpty(i,j,0,8);setcolor(7);DrawSmile();randomize();SpreadMine(8);}voidShowWhite(inti,intj){if(Mine[i][j].flag==1||Mine[i][j].num==0) /*该格处理过久不对该格进行任何处理*/return;minenum--;if(Mine[i][j].roundnum==0&&Mine[i][j].num!=1){DrawEmpty(i,j,1,7);Mine[i][j].num=0;}elseif(Mine[i][j].num!=0){DrawEmpty(i,j,0,8);sprintf(randminenum,"%d",Mine[i][j].roundnum);outtextxy(195+j*20,95+i*20,randminenum);Mine[i][j].num=0;return;}if(i!=0&&j!=0&&Mine[i][j].num!=1)ShowWhite(i-1,j-1);if(i!=0&&j!=9&&Mine[i][j].num!=1)ShowWhite(i-1,j+1);if(i!=9&&j!=0&&Mine[i][j].num!=1)ShowWhite(i+1,j-1);if(i!=9&&j!=9&&Mine[i][j].num!=1)ShowWhite(i+1,j+1);if(i!=0&&Mine[i][j].num!=1)ShowWhite(i-1,j);if(i!=9&&Mine[i][j].num!=1)ShowWhite(i+1,j);if(j!=0&&Mine[i][j].num!=1)ShowWhite(i,j-1);if(j!=9&&Mine[i][j].num!=1)ShowWhite(i,j+1);}voidControl(){intgameFlag=1; /*游戏失败后判断是否重新开始的标志*/while(1){if(gameFlag) /*判断出重新开始或者推出游戏就继续*/{GameBegain(); /*游戏开始*/GamePlay(); /*游戏具体实现*/if(gameAgain==1){gameAgain=0;continue;}}MouseOn();gameFlag=0;if(LeftPress()) /*判断是否重新开始*/{MouseGetXY();if(MouseX>280&&MouseX<300&&MouseY>65&&MouseY<85){gameFlag=1;continue;}}if(kbhit())break;}MouseOff();}voidGamePlay(){inti,j,num; /*num用于接收一个格子周围右多少地雷*/for(i=0;i<10;i++)for(j=0;j<10;j++)Mine[i][j].roundnum=MineStatistics(i,j);while(!kbhit()) /*kbhit(有键盘输入,若有则返回一个非0值,否
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 玻璃纤维增强塑料门进场检验方案
- 一般工业固体废物分类处置项目技术方案
- 消能阻尼器安装施工方案
- 污水自控系统集成方案
- 车间空压机余热利用改造工程竣工验收报告
- 闭口型压型金属板节点处理方案
- 隧道洞门施工方案
- 新质生产力导向下财务管理模式革新策略
- 屋面板拼缝密封控制方案
- 绿色甲醇生产项目技术方案
- 2026年高考英语新高考一卷真题卷附答案
- 国开《离散数学》大作业及答案
- 苏教版四年级数学下册第七单元《三角形平行四边形和梯形》测试卷(含答案)
- 健康生活预防癌症智慧树知到期末考试答案2024年
- 《车险基础知识培训》
- 《外科实习作》课件
- 通用电子嘉宾礼薄
- 珠宝回购协议
- 2023年山东财经大学燕山学院教师招聘考试笔试题库及答案
- 钢轨打磨设备及运用 课件 06 电气系统
- 15D503利用建筑物金属体做防雷及接地装置安装图集
评论
0/150
提交评论