我们平时会玩一种叫扫雷的游戏,那么扫雷如何用C语言来实现呢,今天我们就来编写扫雷的小游戏(优先看头文件中的宏定义)。
游戏编写基础
对于游戏的编写我们都已经较为熟悉,创建完菜单和swith函数之后就是对游戏的编写了,代码如下:
对主函数的编写:
int main() { int input = 0; do { menu(); printf("请选择>:"); scanf("%d", &input); switch(input) { case 1: game(); break; case 0: printf("退出游戏\n"); break; default: printf("输入错误,请重新输入!\n"); break; } } while (input); return 0; }
对菜单的编写:
void menu() { printf("*********************************\n"); printf("************ 1.play *************\n"); printf("************ 0.exit *************\n"); printf("*********************************\n"); }
PS:为了之后的防止数组越界,将棋盘设为11*11。
内容编写
接下来就是对游戏内容的编写了,游戏原来的是这样的:
这里我们就简单一点,创建一个9*9的棋盘就可以了
mine[9][9]
接下来就是对内容编写的思路:
编写思路:
1.首先,对创建的棋盘进行初始化,这里我们为了方便,将字符‘1’设为雷,方便之后计算雷的个数,但这同时也产生一个问题,计算的雷的个数如果为1,则会影响判断,所以我们将创建两个棋盘。
2.我们需要埋雷,对雷的埋放采用随机的方法。
3.玩家选择后,进行判断:1.是雷,游戏结束。
2.不是雷,计算该坐标周围雷的个数,方便玩家对接下来判断。
3.找出所有雷的个数后,游戏也会结束。
1.初始化棋盘
首先对棋盘进行初始化,代码如下:
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set) { int i = 0; int j = 0; for (i = 0; i < rows; i++) { for (j = 0; j < cols; j++) { board[i][j] = set; } } }
PS:这里是将创建的两个棋盘一同初始话,埋雷的棋盘初始化为字符‘0’,让玩家游玩的棋盘初始化为‘*’。
2.打印棋盘
为了方便玩家进行判断,我们将行和列打印出来,代码如下:
void DisplayBoard(char board[ROWS][COLS], int row, int col) { int i = 0; int j = 0; printf("--------扫雷---------\n");//修饰 for (i = 0; i <= col; 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"); } printf("--------扫雷---------\n"); }
3.埋雷
埋雷的过程需要注意,不得在有雷的坐标上再次埋雷,需要避免,(这里使用的随机值,需要在主函数中引用srand)代码如下:
void Setmine(char mine[ROWS][COLS], int row, int col) { int count = EASY_COUNT; while (count) { int x = rand()% row + 1; int y = rand()% col + 1; if (mine[x][y] == '0') { mine[x][y] = '1'; count--; } } }
4.玩家扫雷
玩家输入坐标后会进行扫雷,判断是否合法,之后对扫雷的过程思路中说得很清楚,这里不过多赘述,代码如下:
void Findmine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col) { int x = 0; int y = 0; int win = 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"); DisplayBoard(mine, ROW, COL); break; } else { int c = GetMineCount(mine, x, y); show[x][y] = c + '0'; DisplayBoard(show, ROW, COL); win++; } } else { printf("坐标非法,请重新输入!\n"); } }
PS:整形与字符的转换需要+-字符'0'。
完整代码
test.c(主函数)代码:
#include "game.h" void menu() { printf("*********************************\n"); printf("************ 1.play *************\n"); printf("************ 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,'*'); DisplayBoard(show, ROW, COL); //布置雷 Setmine(mine, ROW, COL); //排查雷 Findmine(mine, show,ROW, COL); } int main() { srand((unsigned int)time(NULL)); int input = 0; do { menu(); printf("请选择>:"); scanf("%d", &input); switch(input) { case 1: game(); break; case 0: printf("退出游戏\n"); break; default: printf("输入错误,请重新输入!\n"); break; } } while (input); return 0; }
game.c(函数编写)
#include "game.h" void InitBoard(char board[ROWS][COLS], int rows, int cols, char set) { int i = 0; int j = 0; for (i = 0; i < rows; i++) { for (j = 0; j < cols; j++) { board[i][j] = set; } } } void DisplayBoard(char board[ROWS][COLS], int row, int col) { int i = 0; int j = 0; printf("--------扫雷---------\n");//修饰 for (i = 0; i <= col; 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"); } printf("--------扫雷---------\n"); } void Setmine(char mine[ROWS][COLS], int row, int col) { int count = EASY_COUNT; while (count) { int x = rand()% row + 1;//产生随机坐标来布置雷 int y = rand()% col + 1; if (mine[x][y] == '0')//确保可以布置雷 { mine[x][y] = '1'; count--; } } } int GetMineCount(char mine[ROWS][COLS], int x, int y) { int num = mine[x - 1][y - 1] + mine[x - 1][y] + mine[x - 1][y + 1] + mine[x][y + 1] + mine[x + 1][y + 1] + mine[x + 1][y] + mine[x + 1][y - 1] + mine[x][y - 1] - 8 * '0'; return num; } void Findmine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col) { int x = 0; int y = 0; int win = 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"); DisplayBoard(mine, ROW, COL); break; } else { //不是雷,统计雷的数量(‘0’-‘0’=0) int c = GetMineCount(mine, x, y); show[x][y] = c + '0'; DisplayBoard(show, ROW, COL); win++; } } else { printf("坐标非法,请重新输入!\n"); } } }
game.h(头文件 )
#include<stdio.h> #include<stdlib.h> #include<time.h> #define ROW 9 #define COL 9 #define ROWS 11 #define COLS 11 #define EASY_COUNT 10 //初始化棋盘 void InitBoard(char board[ROWS][COLS], int rows, int cols, char set); //显示棋盘 void DisplayBoard(char board[ROWS][COLS],int row,int col); //布置雷 void Setmine(char mine[ROWS][COLS], int row, int col); //排查雷 void Findmine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
结尾
其实代码还可以进行加强,比如我们在玩扫雷时会将没有雷的坐标一并排除,就像这样:
可以升级代码,将玩家点击的坐标周围没有雷的区域也一并排除(还可以将雷进行插旗排除),但小编技术有限,还需要继续学习。
到这里 就结束啦,我们下次见。