史前扫雷
文章目录
前言
大家好!上次做个三子棋往死里欺负电脑,没什么意思今天就来做个原始扫雷体验一下被地雷炸上天的快感,说实话没做这个小游戏之前我都没玩过扫雷,后来去找度娘玩了一把才知道这玩意是怎么回事,就是用鼠标去点击给定区域上的某一个位置,如果你不小心点钟地雷那么你被炸死,当你某过了所有的雷也就意味着你赢了,接下来就来实现朴素版的扫雷 。
扫雷思维导图
创建项目所需的文件
- 1.text.c
- 2.game.c
- 3.game.h
和三子棋一样分文件来写,方便管理文件。其中text.c用来测试扫雷游戏,所以将主函数编写在这里,在这里面调用实现游戏的函数,并完成游戏。game.c专门用来写实现扫雷游戏的函数,game.h声明函数和预定义常量的地方。
game.h
先上头文件,谁让它是头,没有它没有game.c,没有game.c就没有游戏了。
#define _CRT_SECURE_NO_WARNINGS 1 //实际所用棋盘9*9 #define ROW 9 #define COL 9 #define ROWS ROW+2 #define COLS COL+2//实际大小11*11 #define EASY_COUNT 80 //雷的个数 #include<stdio.h> #include<stdlib.h> #include<time.h> //声明函数 void InitBoard(char board[ROWS][COLS], int rows, int cols,char ret); void DispalyBoard(char board[ROWS][COLS],int row,int col); void SetMine(char board[ROWS][COLS], int row,int col); void FindMine(char mine[ROWS][COLS], char show [ROWS][COLS], int row, int col);
text.c(main)
和三子棋初始设计都是一样的都是游戏自然需要一个菜单供用户选择,所以还是从游戏菜单部分开始写
实现游戏菜单
void menu() { printf("***欢迎来到扫雷荣耀***\n"); printf("****1.play 0.exit****\n"); printf("*********************\n"); } //在main方法里面实现游戏菜单
菜单中有两种选择,玩家选1则开始游戏,选2则退出游戏。如果玩家一不小心输入有还会有温馨提示,让玩家重新输入。实现选择这个功能我们可以用switch语句然后在调用相应的函数即可,仅仅是这样还是不够,因为仅仅这样的话游戏玩一把就结束了,这就跟王者只给你玩一把一样,你肯定得不到满足,而被玩的一方也相应的得不到满足。所以为了让玩家无限循环的玩下去,这就得加个循环来实现。
菜单功能实现
void text() { int input = 0; srand((unsigned int)time(NULL)); do { menu(); printf("请输入你的选择:>"); scanf("%d", &input); switch (input) { case 1: //game(); printf("扫雷\n"); break; case 0: printf("退出游戏!"); break; default: printf("你输入的有误,请重新输入!"); break; } } while (input); } //main中
咋们设计的游戏规定1为雷0不是雷,这就存在一个bug当我们玩游戏时如果选中一个没有雷的区域,那么它还要计算出它周围有没有雷,有雷的话就要记录下来,假如周围就一个雷,那么现实在该区域的数字也是1,那么问题来了?这个1到底是雷还是雷的数量呢?这就无从知晓了。所以为了解决这个问题我们创建2个棋盘一个用来埋雷,一个用来记录排查出雷的信息,为了使扫雷游戏更贴近于真实的效果,所以就用※放在空白区域。
game.c
创建棋盘
char mine[ROWS][COLS] = { 0 };//埋雷 char show[ROWS][COLS] = { 0 };//扫雷
初始化棋盘
InitBoard(mine,ROWS, COLS,'0');//埋雷,此区域不能给玩家看不然就没的玩了,初始化为0暂时未埋雷 InitBoard(show, ROWS, COLS, '*');//记录雷的信息,即玩家所见的区域,初始化为*,记录雷的个数,统计出后自动替换* //InitBoard();函数的实现 void InitBoard(char board[ROWS][COLS], int rows, int cols, char ret) { int i = 0, j = 0; for (i = 0; i < rows; i++) { for (j = 0; j < cols; j++) { board[i][j] = ret; } } }
打印棋盘
/*DispalyBoard(mine, ROW, COL);*/ /*DispalyBoard(show, ROW, COL);*/ //DispalyBoard(show, ROW, COL);函数实现 给玩家看的棋盘 void DispalyBoard(char board[ROWS][COLS], int row, int col) { int i = 0, j = 0; for (i = 0;i<=row;i++) { printf("%d ", i);//打印列号 } printf("\n"); for (i = 1; i <= row; i++) { //打印行号 printf("%d ", i); for (j = 1;j <= col; j++) { printf("%c ", board[i][j]); } printf("\n"); } }
看看啥熊样子
就这熊样,行和列的数字标出来方便玩家输入数字确定坐标
布置雷阵
/ /布置雷 //SetMine(mine ,ROW ,COL); //SetMine();函数实现 void SetMine(char board[ROWS][COLS], int row, int col) { int count = EASY_COUNT; while (count) { int x = rand() % row + 1;//模row x>=0&&x<8 所以+1 --> x>=1&&x<=9 int y = rand() % col + 1;//模col x>=0&&x<8 所以+1 --> x>=1&&x<=9 if(board[x][y]=='0') { board[x][y] = '1'; count--; } } }
80个雷爽歪歪,不炸死也得死。
排雷
//FindMine(mine, show, ROW, COL); //FindMine();函数实现 void SetMine(char board[ROWS][COLS], int row, int col) { int count = EASY_COUNT; while (count) { int x = rand() % row + 1;//模row x>=0&&x<8 所以+1 --> x>=1&&x<=9 int y = rand() % col + 1;//模col x>=0&&x<8 所以+1 --> x>=1&&x<=9 if(board[x][y]=='0') { board[x][y] = '1'; count--; } } }
炸死or胜利
int get_mine_count(char mine[ROWS][COLS],int x,int y)//一某一个点为中心向四周搜寻雷 方位:(上,下,左,右,右上,右下,左下,左上) { return mine[x - 1][y] + mine[x - 1][y - 1] + mine[x][y - 1] + mine[x + 1][y - 1] + mine[x + 1][y + 1] + mine[x][y + 1] + mine[x - 1][y + 1] - 8 * '0';//'3'-'3'==0 --->'1'-'0'==1--> 'n'-8*'0'==数字 字符转数字 } void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col) { int win = 0; int x = 0; int y = 0; while (win< row * col - EASY_COUNT) { printf("请输入排查的坐标:>"); scanf("%d %d",&x, &y); if (x >= 1 && x <= row && y >= 1 && y <= col) { if (mine[x][y] == '1') { printf("很遗憾,你被炸死了!\n"); DispalyBoard(mine, ROW, COL);//让玩家死的明白 break; } else { int count = get_mine_count(mine, x, y); show[x][y] = count + '0'; DispalyBoard(show, ROW, COL); win++; } } else { printf("输入的坐标非法,请重新输入!\n"); } if (win == row * col - EASY_COUNT) { printf("恭喜你排雷成功!\n"); } } }
所有代码
game.h #define ROW 9 #define COL 9 #define ROWS ROW+2 #define COLS COL+2 #define EASY_COUNT 80 #include<stdio.h> #include<stdlib.h> #include<time.h> //声明函数 void InitBoard(char board[ROWS][COLS], int rows, int cols,char ret); void DispalyBoard(char board[ROWS][COLS],int row,int col); void SetMine(char board[ROWS][COLS], int row,int col); void FindMine(char mine[ROWS][COLS], char show [ROWS][COLS], int row, int col); game.c #include"game.h" void InitBoard(char board[ROWS][COLS], int rows, int cols, char ret) { int i = 0, j = 0; for (i = 0; i < rows; i++) { for (j = 0; j < cols; j++) { board[i][j] = ret; } } } void DispalyBoard(char board[ROWS][COLS], int row, int col) { int i = 0, j = 0; for (i = 0;i<=row;i++) { printf("%d ", i);//打印列号 } printf("\n"); for (i = 1; i <= row; i++) { //打印行号 printf("%d ", i); for (j = 1;j <= col; j++) { printf("%c ", board[i][j]); } printf("\n"); } } void SetMine(char board[ROWS][COLS], int row, int col) { int count = EASY_COUNT; while (count) { int x = rand() % row + 1;//模row x>=0&&x<8 所以+1 --> x>=1&&x<=9 int y = rand() % col + 1;//模col x>=0&&x<8 所以+1 --> x>=1&&x<=9 if(board[x][y]=='0') { board[x][y] = '1'; count--; } } } int get_mine_count(char mine[ROWS][COLS],int x,int y) { return mine[x - 1][y] + mine[x - 1][y - 1] + mine[x][y - 1] + mine[x + 1][y - 1] + mine[x + 1][y + 1] + mine[x][y + 1] + mine[x - 1][y + 1] - 8 * '0'; } void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col) { int win = 0; int x = 0, y = 0; while (win< row * col - EASY_COUNT) { printf("请输入排查的坐标:>"); scanf("%d %d",&x, &y); if (x >= 1 && x <= row && y >= 1 && y <= col) { if (mine[x][y] == '1') { printf("很遗憾,你被炸死了!\n"); DispalyBoard(mine, ROW, COL); break; } else { int count = get_mine_count(mine, x, y); show[x][y] = count + '0'; DispalyBoard(show, ROW, COL); win++; } } else { printf("输入的坐标非法,请重新输入!\n"); } if (win == row * col - EASY_COUNT) { printf("恭喜你排雷成功!\n"); } } } text.c #include<stdio.h> #include"game.h" void menu() { printf("***欢迎来到扫雷荣耀***\n"); printf("****1.play 0.exit****\n"); printf("*********************\n"); } void game() { char mine[ROWS][COLS] = { 0 };//埋雷 char show[ROWS][COLS] = { 0 };//扫雷 //初始化棋盘 InitBoard(mine,ROWS, COLS,'0'); InitBoard(show, ROWS, COLS, '*'); //打印棋盘 //DispalyBoard(mine, ROW, COL); //DispalyBoard(show, ROW, COL); //布置雷 SetMine(mine ,ROW ,COL); /*DispalyBoard(mine, ROW, COL);*/ /*DispalyBoard(mine, ROW, COL);*/ //扫雷 DispalyBoard(show, ROW, COL); FindMine(mine, show, ROW, COL); } void text() { int input = 0; srand((unsigned int)time(NULL)); do { menu(); printf("请输入你的选择:>"); scanf("%d", &input); switch (input) { case 1: game(); //printf("扫雷\n"); break; case 0: printf("退出游戏!"); break; default: printf("你输入的有误,请重新输入!"); break; } } while (input); } int main() { text(); return 0; }
结束语
没有【永恒】这个单词能够延长到它所代表的词意的【可能性】,也没有面对所有【风浪】的时候的【淡定】。
我从来表里都没有如一,也从来没有逃离【暗色】的阴影。 – 墨九夏 《恰若风华正茂时》
我的github欢迎来访,github