扫雷游戏(C语言实现)初级版和优化版(增加了自动展开标记地雷功能,同时排除了第一次排到地雷的情况)
Posted fy_闷油瓶
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了扫雷游戏(C语言实现)初级版和优化版(增加了自动展开标记地雷功能,同时排除了第一次排到地雷的情况)相关的知识,希望对你有一定的参考价值。
文章目录
一、初级版扫雷
1.1 游戏功能
初级版只具备最基础的两个功能:
1、显示当前输入坐标周围雷的数目
2、排雷错误,则游戏结束
3、当排除所有的非雷区域后,取得胜利
1.2 设计思路
我们以9*9的格子(我们称为棋盘)为例。
首先,我们需要两个数组,其中一个用来布置地雷的位置(这个数组不对玩家显示),另一个用来显示排雷的信息。
假设我们现在要统计坐标(1,1)和(3,4)周围雷的数目,坐标(3,4)需要统计周围8个位置是否有雷,坐标(1,1)只用统计周围三个位置是否有雷,在棋盘中,大多数格子都被8个格子所包围,而边界位置旁边有3或5个格子,如果分别进行判断的话,需要讨论多种情况,因此我们将棋盘扩大为11 *11。有效区域只有中间的9 *9部分,这样对于每一个位置,都是统计周围8个格子是否有雷。
运行效果:
在游戏开始前,我们打印一个游戏菜单供玩家进行选择,当玩家选择了开始游戏后,我们进入游戏模块。
void menu()
printf("**********************************************\\n");
printf("********请选择-> 1:开始游戏 0:结束游戏****\\n");
printf("**********************************************\\n");
int main()
int input = 0;
srand((unsigned int)time(NULL)); //初始化种子
do
menu(); //打印菜单
scanf("%d",&input);
switch (input)
case 1:
printf("扫雷游戏开始:\\n");
game();
break;
case 0:
printf("退出游戏\\n");
break;
default:
printf("输入错误,请重新输入\\n");
break;
while (input);
return 0;
当玩家选择开始游戏后,我们要先创建两个数组,并将其初始化。存放地雷的数组,先将其全部初始化为字符’0’;存放排雷信息的数组先全部初始化为字符 ’ * '。
游戏模块:
void game()
char Myboard[ROWS][COLS] = 0 ; //用来存放地雷
char ShowBoard[ROWS][COLS] = 0 ; //用来显示排雷的信息
InitBoard(Myboard, ROWS, COLS, '0'); //将地雷棋盘全部初始化为0
InitBoard(ShowBoard, ROWS, COLS, '*'); //将显示棋盘全部初始化为*
SetBoard(Myboard, ROW, COL); //布雷
PrintBoard(ShowBoard, ROWS, COLS); //打印棋盘
FindBoard(Myboard,ShowBoard, ROWS, COLS); //排雷
初始化模块:
void InitBoard(char board[ROWS][COLS], int row, int col, char c) //初始化棋盘
int i = 0, j = 0;
for (i = 0; i < row; i++)
for (j = 0; j < col; j++)
board[i][j] = c;
然后我们使用srand和rand函数随机布置地雷的位置(srand函数要放在主函数的循环体外)因为棋盘的有效区域只有中间的9 *9部分,因此我们要确保rand产生的随机数在1-9这个范围内。
void SetBoard(char board[ROWS][COLS], int row, int col) //布雷
for (int cnt = 0; cnt < COUNT;)
int x = rand() % row + 1; //随机产生横纵坐标
int y = rand() % col + 1;
if (board[x][y] == '0')
board[x][y] = '1';
cnt++;
当布置好雷之后,我们打印显示棋盘,在打印的同时打印上横纵序号,方便玩家确定坐标
void PrintBoard(char board[ROWS][COLS], int row, int col) //打印棋盘
printf(" ");
for (int i = 1; i < row - 1; i++) //打印列坐标
printf("%d ", i);
printf("\\n");
for (int i = 1; i < row - 1; i++)
printf("%d ", i); //打印横坐标
for (int j = 1; j < col - 1; j++)
printf("%c ", board[i][j]);
printf("\\n");
最后是游戏的核心部分:排雷
当玩家输入的坐标不是雷,统计周围8个位置雷的数目,可以用8个if语句或者循环语句来统计,此处我将每个位置的字符相加,最后减去8个’0’,也是雷的数目。
int Num(char board[ROWS][COLS], int x, int y) //统计当前位置周围有几个雷
return board[x - 1][y - 1] + board[x - 1][y] + board[x - 1][y + 1] +
board[x][y - 1] + board[x][y + 1] +
board[x + 1][y - 1] + board[x + 1][y] + board[x + 1][y + 1] - 8 * '0';
//如果是雷,则对应的坐标位置是字符 '1',否则是字符'0',将周围八个位置的字符全部相加最后减去8个字符'0',就是周围雷的数目
//'1' - '0' = 1(数字1) '0' - '0' = 0(数字0)
void FindBoard(char board[ROWS][COLS], char ShowBoard[ROWS][COLS], int row, int col) //排雷
int x = 0;
int y = 0;
int cnt = ROW * COL - COUNT; //cnt表示非雷的数目,即棋盘大小减去地雷数
while (1)
printf("请输入坐标\\n");
scanf("%d%d", &x, &y);
if (x < 1 || x >row || y < 1 || y > col)
printf("坐标非法,请重新输入\\n");
else
if (board[x][y] == '1') //当前坐标位置是雷,游戏结束
printf("你失败了,游戏结束\\n");
PrintBoard(board, row, col);
break;
else if (board[x][y] == '0') //当前坐标不是雷,统计周围雷的数目
if (0 == Num(board, x, y)) //如果周围没有雷,则当其置为空
ShowBoard[x][y] = ' ';
else ShowBoard[x][y] = Num(board, x, y) + '0'; //周围有雷,将其置为雷的个数
//(因为我们打印的是字符型变量,因此要加上'0'才是所对应的数字字符)
cnt--; //每排完一个雷,非雷的数目减1
PrintBoard(ShowBoard, row, col); //打印当前显示棋盘的信息
if (cnt == 0)
printf("恭喜你,成功排雷\\n");
PrintBoard(board, row, col);
break;
我们将代码分别封装在main.c和game.c两个文件中,并在game.h头文件中对函数进行声明
main.c
#include"game.h"
void menu()
printf("**********************************************\\n");
printf("********请选择-> 1:开始游戏 0:结束游戏****\\n");
printf("**********************************************\\n");
void game()
char Myboard[ROWS][COLS] = 0 ; //用来存放地雷
char ShowBoard[ROWS][COLS] = 0 ; //用来显示排雷的信息
InitBoard(Myboard, ROWS, COLS, '0'); //将地雷棋盘全部初始化为0
InitBoard(ShowBoard, ROWS, COLS, '*'); //将显示棋盘全部初始化为*
SetBoard(Myboard, ROW, COL); //布雷
PrintBoard(ShowBoard, ROWS, COLS);
FindBoard(Myboard,ShowBoard, ROWS, COLS); //排雷
int main()
int input = 0;
srand((unsigned int)time(NULL)); //初始化种子
do
menu(); //打印菜单
scanf("%d",&input);
switch (input)
case 1:
printf("扫雷游戏开始:\\n");
game();
break;
case 0:
printf("退出游戏\\n");
break;
default:
printf("输入错误,请重新输入\\n");
break;
while (input);
return 0;
game.c
void InitBoard(char board[ROWS][COLS], int row, int col, char c) //初始化棋盘
int i = 0, j = 0;
for (i = 0; i < row; i++)
for (j = 0; j < col; j++)
board[i][j] = c;
void PrintBoard(char board[ROWS][COLS], int row, int col) //打印棋盘
printf(" ");
for (int i = 1; i < row - 1; i++) //打印列坐标
printf("%d ", i);
printf("\\n");
for (int i = 1; i < row - 1; i++)
printf("%d ", i); //打印横坐标
for (int j = 1; j < col - 1; j++)
printf("%c ", board[i][j]);
printf("\\n");
void SetBoard(char board[ROWS][COLS], int row, int col) //布雷
for (int cnt = 0; cnt < COUNT;)
int x = rand() % row + 1; //随机产生横纵坐标
int y = rand() % col + 1;
if (board[x][y] == '0')
board[x][y] = '1';
cnt++;
int Num(char board[ROWS][COLS],int x,int y) //统计当前位置周围有几个雷
return board[x - 1][y - 1] + board[x - 1][y] + board[x - 1][y + 1] +
board[x][y - 1] + board[x][y + 1] +
board[x + 1][y - 1] + board[x + 1][y] + board[x + 1][y + 1] - 8 * '0';
void FindBoard(char board[ROWS][COLS], char ShowBoard[ROWS][COLS], int row, int col) //排雷
int x = 0;
int y = 0;
int cnt = ROW * COL - COUNT; //cnt表示非雷的数目,即棋盘大小减去地雷数
while (1)
printf("请输入坐标\\n");
scanf("%d%d", &x, &y);
if (x < 1 || x >row || y < 1 || y > col)
printf("坐标非法,请重新输入\\n");
else
if (board[x][y] == '1') //当前坐标位置是雷,游戏结束
printf("你失败了,游戏结束\\n");
PrintBoard(board, row, col);
break;
else if (board[x][y] == '0') //当前坐标不是雷,统计周围雷的数目
if (0 == Num(board, x, y)) //如果周围没有雷,则当其置为空
ShowBoard[x][y] = ' ';
else ShowBoard[x][y] = Num(board, x, y) + '0'; //周围有雷,将其置为雷的个数
//(因为我们打印的是字符型变量,因此要加上'0'才是所对应的数字字符)
cnt--; //每排完一个雷,非雷的数目减1
PrintBoard(ShowBoard, row, col); //打印当前显示棋盘的信息
if (cnt == 0) //所有非雷位置均排查完
printf("恭喜你,成功排雷\\n");
PrintBoard(board, row, col);
break;
二、优化版扫雷
2.1 优化功能
在初级版扫雷中,我们必须一个一个地将所有非雷位置全部排查完才能完成游戏的胜利,提示的信息特别少,并且如果运气不好,第一次就可能排到雷的位置。在优化版扫雷中,增加了自动展开、防止第一次就排到雷的情况同时增加了标记功能。
2.2 设计思路
1、展开功能
当输入一个坐标,如果它的周围没有雷,则将其周围不是雷的区域展开,如果它周围的格子周围也没有雷,则继续展开。
同时为了防止数组越界,在统计雷的数目函数里增加一个if语句来判断。同时为了记录在展开函数中,展开了多少个格子,我们将展开函数返回值设为int,用来记录展开了多少格子。
int Num(char board[ROWS][COLS],int x,int y) //统计当前位置周围有几个雷
if (x >= 1 && x <= ROW && y >= 1 && y <= COL) //防止数组越界
return board[x - 1][y - 1] + board[x - 1][y] + board[x - 1][y + 1] +
board[x][y - 1] + board[x][y + 1C语言实现扫雷小游戏(初级版)