C语言开发简易版扫雷小游戏_第1页
C语言开发简易版扫雷小游戏_第2页
C语言开发简易版扫雷小游戏_第3页
C语言开发简易版扫雷小游戏_第4页
C语言开发简易版扫雷小游戏_第5页
已阅读5页,还剩11页未读 继续免费阅读

下载本文档

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

文档简介

1、C语言开发简易版扫雷小游戏本文给大家分享的是一个使用C语言开发的命令行下的简易版扫雷小游戏,本身没有什么太多的技术含量,只不过是笔者的处女作,所以还是推荐给大家,希望对大家学习C能够有所帮助。前言:想起来做这个是因为那时候某天知道了原来黑框框里面的光标是可以控制的,而且又经常听人说起这个,就锻炼一下好了。之前就完成了那1.0的版本,现在想放上来分享却发现有蛮多问题的,而且最重要的是没什么注释【果然那时候太年轻】!现在看了也是被那时候的自己逗笑了,就修改了一些小bug,增加了算是详尽而清楚的注释,嗯,MSDN上面对各种函数的解释很详细的【又锻炼一下英语】,顺便让开头和结尾的展示“动”了起来,就当

2、作1.5的版本好了。这个只是给出了一个实现的思路,其中肯定也有很多不合理的地方和可优化之处,希望能供大家参考和交流。过程:期间也是遇到了蛮多困惑的。1.最先的是怎么知道按了方向键,左查右找,说法有好几个版本呢,就想看能不能自己测试一下自己的好了,再查再找,好了,感谢写了测试方向键的人;2.再比如说怎么消除窗口中一行的缓冲,因为不消除就一直在哪,视觉效果不好,翻查了一下资料,就写了delLine()这个来做这个事情了;3.设定颜色时,在cmd里面help color知道了颜色的参数,但是通过数字0-9来设定的太暗了,发现有更亮的,比如0A,在setColor()里面用它却说类型不对,于是上MSD

3、N,发现还可以用宏,就想通过如'BACKGROUND_INTENSITY | BACKGROUND_RED '之类来完成,就想怎么去代替那个宏,觉得每次写一长串好麻烦。然后换了各种类型的参数类型和不定长参数什么的,发现还是不行,后来一想,万一它支持数字10呢,A不就是10么?!一测,成了;4.还有一些判断状态的顺序,嗯啊,这些要先想好再下手,不然左改右改很麻烦呢;5.别的困惑不怎么记得了。代码:下面分别给出LittleMines【好弱的名字】,测试颜色,测试方向键的代码。【反映说有行号不好复制,那取消好了】/* c语言命令行+方向键简易版扫雷* Author:AnnsShado

4、W* Version:1.5* Time:2015-11-29*/* 运行环境:Windows10-64bit* 编译环境:Codeblocks-13.12*/用到的都导进去吧#include <stdio.h>#include <stdlib.h>#include <conio.h>#include <time.h>#include <windows.h>/定义各种判断状态的ASCII码/MINE是定义翻开格子中的*'号#define MINE 42#define ESC 27#define ENTER 13#define

5、SPACE 32#define UP 72#define DOWN 80#define LEFT 75#define RIGHT 77/定义类型状态,方便后续判断#define bool int#define true 1#define false 0#define ROW 10#define COLUMN 10#define ALL_MINES 15/当前位置的结构体typedef struct currentPosition_structint x;int y; currentPosition;/每一个小格的结构体typedef struct blockCondition_struct/是

6、否被覆盖了bool beCovered;/以它为中心周围的雷数int minesNum; blockCondition;/光标的位置数组currentPosition cursorPosROWCOLUMN;/雷区地图的数组blockCondition minesMapROWCOLUMN;/剩下的格子数int leftBlocksNum = ROW * COLUMN;/光标在光标位置、雷区地图中的下标int index_x = 0, index_y = 0;/设置窗口前后背景色void setColor(unsigned short color);/开头的欢迎“动画”void welcomeTo

7、MyGame();/游戏地图初始化void gameInitailize();/以某格子为中心计算惊天雷数量void countMines();/获取键盘的输入void keyBoardInput();/指定光标的位置void setCurPos(int y, int x);/移动光标的位置void moveCursor(int y, int x);/检测每一步的结果bool checkResult(int y, int x);/输出游戏界面void printMap();/游戏退出后的“动画”void gameOver(char *str);/删除窗口中一行的缓冲void delLine(i

8、nt y);int main()setColor(10);system("cls");welcomeToMyGame();gameInitailize();countMines();printMap();for(;)setCurPos(cursorPosindex_yindex_x.y, cursorPosindex_yindex_x.x);keyBoardInput();return EXIT_SUCCESS;void setColor(unsigned short color)HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE);/

9、对设置之后的输出有效SetConsoleTextAttribute(hCon, color);void welcomeToMyGame()int i = 0;char introductions0 = "LittleMines"char introductions1 = "-"char introductions2 = "Version 1.5"char introductions3 = "Author:AnnsShadow,hank you ()"/控制台窗口默认大小是80*25,所以能达到最大的位置是79,24

10、for(i = 0; i <= 5; +i)/每次输出之前都清屏,就会有看起来是动的效果system("cls");/纵坐标不断加,形成向下效果setCurPos(i, (80 - strlen(introductions0) / 2);printf("%s", introductions0);/缓冲一下,太快了看不到呢Sleep(50);/为了对称,从边边78开始到中间39好了for(i = 78; i >= 39; -i)/上面用了5行了,大于它吧setCurPos(7, i);printf("%s", introdu

11、ctions1);setCurPos(7, 78 - i);printf("%s", introductions1);Sleep(40);/从左边一步步进入屏幕中间for(i = 0; i <= (80 - strlen(introductions2) / 2; +i)/要删除这一行缓冲的原因:/上一次循环的输出会影响到下一次,如输出VVVVVVVVVVersion1.0/换成中文就不会,中文要两个字节才能显示完整呀delLine(9);/这里就会有闪闪发亮的效果哦Sleep(10);setCurPos(9, i);printf("%s", int

12、roductions2);Sleep(50);/从底部进入for(i = 24; i >= 12; -i)setCurPos(i, (80 - strlen(introductions3) / 2);printf("%s", introductions3);Sleep(20);/删除上一次的缓冲,不加1的话最后一行就会残留,其它都不见了delLine(i + 1);Sleep(50);Sleep(500);char help0 = "动啊:()"char help1 = "点击啊:Space / Enter ()"char he

13、lp2 = "不玩啦:Esc ()"char help3 = "<<愿你玩的开心 _(:)_>>"setCurPos(14, (80 - strlen(help0) / 2);setColor(14);printf("%s", help0);setCurPos(15, (80 - strlen(help1) / 2);printf("%s", help1);setCurPos(16, (80 - strlen(help2) / 2);printf("%s", help2)

14、;setCurPos(17, (80 - strlen(help3) / 2);setColor(15);printf("%s", help3);getch();void gameInitailize()int i = 0, j = 0;int allMines = ALL_MINES;/设置随机值srand(unsigned int)time(NULL);/雷区地图初始化for(i = 0; i < ROW; +i)for(j = 0; j < COLUMN; +j)minesMapij.beCovered = true;minesMapij.minesNum

15、 = 0;/放置惊天雷!while(allMines)i = rand() % ROW;j = rand() % COLUMN;if(minesMapij.minesNum = 0)/这个-1'就作为判断惊天雷的依据了minesMapij.minesNum = -1;-allMines;/光标位置初始化for(i = 0; i < ROW; +i)for(j = 0; j < COLUMN; +j)cursorPosij.x = j * 6 + 3;cursorPosij.y = i * 2 + 1;void countMines()int i = 0, j = 0, m

16、= 0, n = 0;/以格子为中心周围的雷数int minesNum = 0;for(i = 0; i < ROW; +i)for(j = 0; j < COLUMN; +j)/遇到惊天雷就放弃统计吧if(minesMapij.minesNum = -1)continue;minesNum = 0;/九宫格嘛,那3次好了for(m = -1; m <= 1; +m)/行溢出了没,不能算没有的哦if(i + m < 0 | i + m >= ROW)continue;for(n = -1; n <= 1; +n)/这次就是看列溢出了没if(j + n <

17、; 0 | j + n >= COLUMN)continue;/周边有惊天雷赶紧加起来if(minesMapi + mj + n.minesNum = -1)+minesNum;minesMapij.minesNum = minesNum;void keyBoardInput()bool lose;int key1 = getch();/*测试之后才知道方向键两个字节第一个字节ASCII 0x00e0 224第二个字节分别是:上:0x0048 72下:0x0050 80左:0x012b 75右:0x012d 77*/if(key1 = 224)int key2 = getch();swi

18、tch(key2)case UP:moveCursor(index_y - 1, index_x);break;case DOWN:moveCursor(index_y + 1, index_x);break;case LEFT:moveCursor(index_y, index_x - 1);break;case RIGHT:moveCursor(index_y, index_x + 1);break;default:break;elseswitch(key1)case ENTER:case SPACE:lose = checkResult(index_y, index_x);system(

19、"cls");printMap();if(lose)setColor(13);printf("| 诶哟,还差一点点哦! |n");printf("| 按"r"重玩,Esc不玩啦。 |n");printf("%c-%cn", MINE, MINE);setColor(10);Sleep(1000);char key3 = getch();if(key3 = 'r' | key3 = 'R')/重来,跟main中过程是一样的setColor(10);gameInita

20、ilize();countMines();printMap();/剩余的格子比雷还要多,可以继续玩else if(leftBlocksNum > ALL_MINES)setColor(13);printf("| 哎哟,挺不错哦 (0 ) |n");printf("%c-%cn", MINE, MINE);setColor(10);/来到这你已经赢了elsesetColor(13);printf("| 哟,恭喜你赢了(/) |n");printf("| 按"r"重玩,Esc就不玩啦。 |n"

21、);printf("%c-%cn", MINE, MINE);setColor(10);Sleep(1000);char key3 = getch();if(key3 = 'r' | key3 = 'R')setColor(10);gameInitailize();countMines();printMap();break;case ESC:system("cls");gameOver("ttt啦啦啦很逗很扯吧最后感谢你的玩耍呀()nnnnnnnn");default:break;void setCur

22、Pos(int y, int x)/在窗口缓冲中定义每个位置的状态COORD currentPosition;currentPosition.Y = y;currentPosition.X = x;/所以现在的位置是在y,xSetConsoleCursorPtion(GetStdHandle(STD_OUTPUT_HANDLE), currentPosition);void moveCursor(int y, int x)/限定能走的地方if(x >= 0 && x < COLUMN) && (y >= 0 && y <

23、ROW)setCurPos(cursorPosyx.y, cursorPosyx.x);index_x = x;index_y = y;bool checkResult(int y, int x)int i = 0, j = 0;/检测有没有溢出地图了if(x < 0 | x >= COLUMN | y < 0 | y >= ROW)return false;/就是你了!被选中的格子!minesMapyx.beCovered = false;/被惊天雷炸了if(minesMapyx.minesNum = -1)minesMapyx.minesNum = 9;return

24、 true;/如果没有雷,就当作空格吧if(minesMapyx.minesNum > 0 && minesMapyx.minesNum < 9)return false;/九宫格,3x3咯for(i = -1; i <= 1; +i)/检查一下在这一行溢出了没吧if(y + i < 0 | y + i >= ROW)continue;for(j = -1; j <= 1; +j)/这次就到列了吧if(x + j < 0 | x + j >= COLUMN)continue;/如果下一个是没开过的,就检查它吧if(minesMap

25、y + ix + j.beCovered)minesMapy + ix + j.beCovered = false;checkResult(y + i, x + j);return false;void printMap()system("cls");char help0 = ""char help1 = "动啊"char help2 = "Space / Enter"char help3 = "点击啊"char help4 = "Esc 不玩啦"/因为要输出提示,所以地图不

26、能太大了,10x10就差不多了setColor(14);setCurPos(4, 62);printf("%s", help0);setCurPos(6, 62);printf("%s", help1);setCurPos(9, 62);printf("%s", help2);setCurPos(11, 62);printf("%s", help3);setCurPos(14, 62);printf("%s", help4);setCurPos(0, 0);setColor(10);int i

27、= 0, j = 0, k = 0;leftBlocksNum = 0;setColor(11);printf("开-");setColor(10);for(k = 1; k < COLUMN - 1; +k)printf("+-");setColor(11);printf("+-心n");setColor(10);for(i = 0; i < ROW; +i)for(j = 0; j < COLUMN; +j)if(minesMapij.beCovered)+leftBlocksNum;/这个输出的就是格子被覆盖的

28、时候输出的图形,可以换成1-6试试/1-4是正方形的4个角,5-6是双竖线和双横线printf("| %c ", 3);else if(minesMapij.minesNum = -1 | minesMapij.minesNum = 9)printf("| %c ", MINE);else if(minesMapij.minesNum = 0)printf("| %c ", ' ');elseprintf("| %d ", minesMapij.minesNum);printf("|n&q

29、uot;);if(i < ROW - 1)for(k = 0; k < COLUMN; +k)printf("+-");printf("+n");setColor(11);printf("就-");setColor(10);for(k = 1; k < COLUMN - 1; +k)printf("+-");setColor(11);printf("+-好n");setColor(10);void gameOver(char *str)setColor(12);system(&

30、quot;cls");setCurPos(10, 0);int i = 0;do/逐字输出printf("%c", stri);Sleep(60);while(stri+);setColor(15);system("pause");/随意终止程序并返回给OS,0是正常的exit(0);void delLine(int y)HANDLE hOutput;/窗口缓存信息CONSOLE_SCREEN_BUFFER_INFO sbi;DWORD len, nw;/用MSDN上的TCHAR类型跪了,换成char就好char fillchar = ' '/定位光标COOR

温馨提示

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

评论

0/150

提交评论