在编写扫雷小游戏之前,第一,我们应该列出我们想要实现的扫雷小游戏的功能:
1.显示选中的坐标周围的雷的个数。
2.保证第一次选中的坐标不是雷。
3.选中的坐标周围8个格子中没有雷,则展开。

第二,我们应该明白我们需要两个棋盘来实现扫雷游戏:一个棋盘用来展示给玩家,初始界面全为“ * ”
(未翻开的格子),这个页面就是我们常见的扫雷页面。另一个棋盘用来给编写者看,棋盘内只有字符‘1’和字符‘0’
。‘1’代表雷,‘0’代表非雷。使用字符‘1’‘0’来代表雷和非雷有利于我们下一步计算坐标周围雷的个数。

1.初始化棋盘
nitboard(show_board, ROWS, COLS,'*'); //‘*’代表未翻开的坐标 Initboard(mine_board, ROWS,
COLS, '0'); //‘0’代表非雷 void Initboard(char board[ROWS][COLS], int row, int col,
char set) { memset(board, set, row*col * sizeof(board[0][0])); }
2.打印棋盘
void DisPlayboard(char board[ROWS][COLS], int row, int col) { int i = 0; int j
= 0; printf(" "); for (i = 1; 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"); } printf("\n"); }
3.在棋盘中埋入雷。(因为每一次重新开始游戏雷的位置不能重复,所以选择用随机数来埋雷)
void GetBoom(char board[ROWS][COLS], int row, int col) //埋雷 { int x = 0; int y
= 0; int sum = 0; while(1) { x = rand() % row +1; //雷放在1-9的范围里 y = rand() % col
+1; if (1) { board[x][y] = '1'; sum++; if (sum == M) //埋入雷后跳出循环 { break; } } }
4.确保第一次不踩到雷,如果第一次踩到雷,我们就将此位置改为非雷,然后将此处的雷移动到别处未放置雷的位置。
(还要考虑一种特殊情况,即如果第一次落子就获得胜利的情况时后面函数就不用再执行了,所以此函数要改为有返回值的函数,这样在调用此函数时就可以判断是否为一次就获得胜利的情况)
int Judge_first(char mine_board[ROWS][COLS], char show_board[ROWS][COLS], int
row, int col) { int x = 0; int y = 0; int m; int n; printf("请输入要排查的坐标:"); scanf(
"%d%d", &x, &y); while (1) { if (mine_board[x][y] == '1') //如果第一次踩雷,将此坐标改为非雷 {
mine_board[x][y] = '0'; show_board[x][y] = ' '; while (1) { m = rand() % 9 + 1;
n= rand() % 9 + 1; if (m != x && n != y && mine_board[m][n] != '1') { mine_board
[m][n] = '1'; } Open(mine_board, show_board, x, y); if (Full(show_board, ROW,
COL) == 1) //展开后判断是否一次获得胜利 { printf("游戏胜利\n"); DisPlayboard(mine_board, ROW, COL
); return 2; //一次获得胜利返回2 不再执行PlayerMove函数 break; } DisPlayboard(show_board, row,
col); break; } break; } else if (mine_board[x][y] == '0') { show_board[x][y] =
' '; Open(mine_board, show_board, x, y); if (Full(show_board, ROW, COL) == 1) {
printf("游戏胜利\n"); DisPlayboard(mine_board, ROW, COL); return 2; break; }
DisPlayboard(show_board, row, col); break; } } }
5.当坐标周围雷个数为0时,展示周围格子,再以X和Y周围八个坐标分别为中心展开,当坐标周围有雷时不再递归展开,并将雷的个数放在该坐标。
void Open(char mine_board[ROWS][COLS],char show_board[ROWS][COLS], int x, int y
) { int ret = 0; ret = Num(mine_board, x, y); if (ret == 0) //当坐标周围雷个数为0时
打开周围格子 再以X和Y周围八个坐标为中心展开 重复即为递归展开 { show_board[x][y] = ' '; if (x - 1 > 0 && y -
1 > 0 && show_board[x - 1][y - 1] == '*') { Open(mine_board, show_board, x - 1,
y- 1); } if (x - 1 > 0 && y > 0 && show_board[x - 1][y] == '*') { Open(
mine_board, show_board, x - 1, y); } if (x - 1 > 0 && y + 1 <= COL && show_board
[x - 1][y + 1] == '*') { Open(mine_board, show_board, x - 1, y + 1); } if (x > 0
&& y + 1 <= COL && show_board[x][y + 1] == '*') { Open(mine_board, show_board, x
, y + 1); } if (x + 1 < ROW && y + 1 <= COL && show_board[x + 1][y + 1] == '*')
{ Open(mine_board, show_board, x + 1, y + 1); } if (x + 1 <= ROW && y > 0 &&
show_board[x + 1][y] == '*') { Open(mine_board, show_board, x + 1, y); } if (x +
1 <= ROW && y - 1 > 0 && show_board[x + 1][y - 1] == '*') { Open(mine_board,
show_board, x + 1, y - 1); } if (x > 0 && y - 1 > 0 && show_board[x][y - 1] ==
'*') { Open(mine_board, show_board, x, y - 1); } } else if (ret != 0) show_board
[x][y] = Num(mine_board, x, y) + 48; }
6.计算坐标周围一圈中所含雷的个数。
int Num(char board[ROWS][COLS], int x, int y) { int sum = 0; //sum为坐标周围雷的个数 sum
= board[x - 1][y - 1] + board[x][y - 1] + board[x + 1][y - 1] + board[x + 1][y]
+ board[x + 1][y + 1] + board[x][y + 1] + board[x - 1][y + 1] + board[x - 1][y]
- (8 * '0'); return sum; }
7.判断玩家是否排完所有雷。
int Full(char board[ROWS][COLS], int row, int col) { int i; int j; int sum = 0;
//sum为棋盘未翻开格子的个数 for (i = 1; i <= row; i++) { for (j = 1; j <= col; j++) { if (
board[i][j] == '*') sum++; } } if (sum == M) //当未翻开的格子数为雷数时 返回1 return 1; }
8.玩家输入坐标扫雷。
void PlayerMove(char mine_board[ROWS][COLS], char show_board[ROWS][COLS], int
row, int col) { int x = 0; int y = 0; int ret = 0; while (1) { if (Full(
show_board, ROW, COL) == 1) //棋盘未翻开格子等于雷数时玩家胜利 { printf("游戏胜利\n"); DisPlayboard(
mine_board, ROW, COL); break; } printf("请输入坐标:"); scanf("%d%d", &x, &y); if (x
>= 1 && x <= row && y >= 1 && y <= col) { if (mine_board[x][y] == '1')
//玩家踩到雷,游戏结束 { printf("游戏结束\n"); DisPlayboard(mine_board, ROW, COL); break; }
ret= Num(mine_board, x, y); if (ret == 0) //周围没有雷时,展开周围格子 { Open(mine_board,
show_board, x, y); DisPlayboard(show_board, ROW, COL); } else if (ret != 0)
//周围有雷时打印雷的个数 { show_board[x][y] = ret + 48; DisPlayboard(show_board, ROW, COL);
} } else printf("输入错误,请重新输入"); } }
9.函数声明,宏定义,函数的定义实现,测试。
源文件:test.c //主要负责测试整个代码
头文件:game.h //包含函数各种声明,宏定义
源文件:game.c //包含各种函数的定义

test.c
#include"game.h" void menu() { printf("************************************\n")
; printf("************************************\n"); printf("******* 1.play
*******\n"); printf("******* 0.exit *******\n"); printf(
"************************************\n"); } int game() { char show_board[ROWS][
COLS] = { 0 }; char mine_board[ROWS][COLS] = { 0 }; // Initboard(show_board,
ROWS, COLS,'*'); //初始化数组 Initboard(mine_board, ROWS, COLS, '0'); printf("游戏开始\n"
); DisPlayboard(show_board, ROW, COL); //打印玩家雷盘 // GetBoom(mine_board, ROW, COL)
; //埋雷 printf("\n\n\n"); DisPlayboard(mine_board, ROW, COL); //打印雷盘 // if (
Judge_first(mine_board, show_board, ROW, COL) == 2) //如果一次胜利,就不再执行PlayerMove函数
return 2; // PlayerMove(mine_board, show_board, ROW, COL); } void test() { int n
; menu(); do { printf("请输入选项按钮: "); scanf("%d", &n); switch (n) { case 1: game()
; break; case 0: printf("游戏退出\n"); break; default: printf("输入错误,请重新输入\n"); break
; } }while(1); } int main() { srand((unsigned int)time(NULL)); test(); }
game.c
#include"game.h" void Initboard(char board[ROWS][COLS], int row, int col, char
set) { memset(board, set, row*col * sizeof(board[0][0])); } void DisPlayboard(
char board[ROWS][COLS], int row, int col) { int i = 0; int j = 0; printf(" ");
for (i = 1; 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"); } printf("\n"); } void GetBoom(char board[
ROWS][COLS], int row, int col) //埋雷 { int x = 0; int y = 0; int sum = 0; while(1
) { x = rand() % row +1; //雷放在1-9的范围里 y = rand() % col +1; if (1) { board[x][y]
= '1'; sum++; if (sum == M) //埋入所需的雷后跳出循环 { break; } } } } int Judge_first(char
mine_board[ROWS][COLS], char show_board[ROWS][COLS], int row, int col) { int x =
0; int y = 0; int m; int n; printf("请输入要排查的坐标:"); scanf("%d%d", &x, &y); while (
1) { if (mine_board[x][y] == '1') //如果第一次踩雷,将此坐标改为非雷 { mine_board[x][y] = '0';
show_board[x][y] = ' '; while (1) { m = rand() % 9 + 1; n = rand() % 9 + 1; if (
m!= x && n != y && mine_board[m][n] != '1') { mine_board[m][n] = '1'; } Open(
mine_board, show_board, x, y); if (Full(show_board, ROW, COL) == 1)
//展开后判断是否一次获得胜利 { printf("游戏胜利\n"); DisPlayboard(mine_board, ROW, COL); return 2
; //一次获得胜利返回2 不再执行PlayerMove函数 break; } DisPlayboard(show_board, row, col);
break; } break; } else if (mine_board[x][y] == '0') { show_board[x][y] = ' ';
Open(mine_board, show_board, x, y); if (Full(show_board, ROW, COL) == 1) {
printf("游戏胜利\n"); DisPlayboard(mine_board, ROW, COL); return 2; break; }
DisPlayboard(show_board, row, col); break; } } } void PlayerMove(char mine_board
[ROWS][COLS], char show_board[ROWS][COLS], int row, int col) { int x = 0; int y
= 0; int ret = 0; while (1) { if (Full(show_board, ROW, COL) == 1) //棋盘下满玩家胜利 {
printf("游戏胜利\n"); DisPlayboard(mine_board, ROW, COL); break; } printf("请输入坐标:");
scanf("%d%d", &x, &y); if (x >= 1 && x <= row && y >= 1 && y <= col) { if (
mine_board[x][y] == '1') { printf("游戏结束\n"); DisPlayboard(mine_board, ROW, COL);
break; } ret = Num(mine_board, x, y); if (ret == 0) //周围没有雷时,展开周围格子 { Open(
mine_board, show_board, x, y); DisPlayboard(show_board, ROW, COL); } else if (
ret!= 0) //周围有雷时打印雷的个数 { show_board[x][y] = ret + 48; DisPlayboard(show_board,
ROW, COL); } } else printf("输入错误,请重新输入"); } } void Open(char mine_board[ROWS][
COLS],char show_board[ROWS][COLS], int x, int y) { int ret = 0; ret = Num(
mine_board, x, y); if (ret == 0) //当坐标周围雷个数为0时 打开周围格子 再以X和Y周围八个坐标为中心展开 重复即为递归展开
{ show_board[x][y] = ' '; if (x - 1 > 0 && y - 1 > 0 && show_board[x - 1][y - 1]
== '*') { Open(mine_board, show_board, x - 1, y - 1); } if (x - 1 > 0 && y > 0
&& show_board[x - 1][y] == '*') { Open(mine_board, show_board, x - 1, y); } if (
x- 1 > 0 && y + 1 <= COL && show_board[x - 1][y + 1] == '*') { Open(mine_board,
show_board, x - 1, y + 1); } if (x > 0 && y + 1 <= COL && show_board[x][y + 1]
== '*') { Open(mine_board, show_board, x, y + 1); } if (x + 1 < ROW && y + 1 <=
COL&& show_board[x + 1][y + 1] == '*') { Open(mine_board, show_board, x + 1, y +
1); } if (x + 1 <= ROW && y > 0 && show_board[x + 1][y] == '*') { Open(
mine_board, show_board, x + 1, y); } if (x + 1 <= ROW && y - 1 > 0 && show_board
[x + 1][y - 1] == '*') { Open(mine_board, show_board, x + 1, y - 1); } if (x > 0
&& y - 1 > 0 && show_board[x][y - 1] == '*') { Open(mine_board, show_board, x, y
- 1); } } else if (ret != 0) show_board[x][y] = Num(mine_board, x, y) + 48; }
int Num(char board[ROWS][COLS], int x, int y) { int sum = 0; sum = board[x - 1][
y- 1] + board[x][y - 1] + board[x + 1][y - 1] + board[x + 1][y] + board[x + 1][y
+ 1] + board[x][y + 1] + board[x - 1][y + 1] + board[x - 1][y] - (8 * '0');
return sum; } int Full(char board[ROWS][COLS], int row, int col) { int i; int j;
int sum = 0; for (i = 1; i <= row; i++) { for (j = 1; j <= col; j++) { if (board
[i][j] == '*') sum++; } } if (sum == M) return 1; }
game.h
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<string.h> #include
<stdlib.h> #include<time.h> #define ROW 9 #define COL 9 #define ROWS ROW + 2 #
define COLS COL + 2 #define M 10 //所需雷的个数 void test(); int game(); void
Initboard(char board[ROWS][COLS], int row, int col, int set); //初始化数组 void
DisPlayboard(char board[ROWS][COLS], int row, int col); //打印雷盘 void GetBoom(char
board[ROWS][COLS], int row, int col); //安放炸弹 int Judge_first(char mine_board[
ROWS][COLS], char show_board[ROWS][COLS], int row, int col); //保证第一次不是雷 void
PlayerMove(char mine_board[ROWS][COLS], char show_board[ROWS][COLS], int row,
int col); //玩家排雷 void Open(char mine_board[ROWS][COLS],char show_board[ROWS][
COLS], int x, int y); //展开函数 int Num(char mine_board[ROWS][COLS], int x, int y);
//计算坐标周围雷的数量 int Full(char board[ROWS][COLS], int row, int col); //判断雷是否下满

技术
©2019-2020 Toolsou All rights reserved,
Java开发2020年最新常见面试题整理【Spring源码分析】42-@Conditional详解element-ui踩坑记录神仙面试宝典你有了吗?半月看完25大专题,居然斩获阿里P8offer使用css样式设计一个简单的html登陆界面XCTF攻防世界web新手练习_ 9_command_executionJS中的解构赋值的详解与具体用途Python Web 框架elementui 穿梭框 el-transfer 展示列表内容文字过长ConcurrentHashMap实现原理及源码解析