🐒博客名:平凡的小苏
📚学习格言:有志者,事竟成,破釜沉舟,百二秦关终属楚;苦心人,天不负,卧薪尝胆,三千越甲可吞吴。
扫雷思维导图
目录
前言
相信我们再电脑上都玩过扫雷小游戏,每次排查一个位置时都会显示雷周围的个数,如果周围没有雷则进行展开一片。那么我们如何利用代码来实现扫雷呢?由我细细道来:
首先,我们应该实现测试函数,至少进行一次菜单选择,所以用do.......while语句。选择1则进行玩游戏,选择0则退出游戏,输入其他数字则显示输入错误
-
void test()
-
{
-
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);
-
}
然后根据思维导图将需要包含的头文件写在头源文件中,利用宏定义常量是为了以后修改方便,我们这次需要实现的是9*9的扫雷棋盘,当我们将数字改动,就可以实现任意*任意的棋盘
-
#include<stdio.h>
-
#include<stdlib.h>
-
#include<time.h>//时间戳头文件
-
#define ROW 9//行
-
#define COL 9//列
-
#define ROWS ROW+2
-
#define COLS COL+2
-
#define MINE_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 Set_mine(char mine[ROWS][COLS], int row, int col);
//布置雷
-
void Fine_mine(char mine [ROWS][COLS],char show[ROWS][COLS], int row, int col);
//排查雷
初始化棋盘函数实现:
因为需要布置雷和排查雷,所以需要初始化两个数组,所以设置了set,需要初始化哪个,就把需要初始化的字符传过去即可。
-
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)//初始化棋盘
-
{
-
int i =
0;
-
for (i =
0; i < rows; i++)
-
{
-
int j =
0;
-
for (j =
0; j < cols; j++)
-
{
-
board[i][j] =
set;
-
}
-
}
-
}
打印棋盘函数实现:
如果我们初始化好棋盘,我们需要将它打印出来棋盘。或者我们排查一次雷也需要打印棋盘出来给玩家看到。当被炸死也需要打印棋盘给玩家知道在哪里被炸死了
-
void DisplayBoard(char board[ROWS][COLS], int row, int col)//打印棋盘
-
{
-
printf(
"--------扫雷--------\n");
-
for (
int j =
0; j <= col; j++)
-
{
-
printf(
"%d ", j);
-
}
-
printf(
"\n");
-
for (
int i =
1; i <= row; i++)
-
{
-
printf(
"%d ",i);
-
for (
int j =
1; j <= col; j++)
-
{
-
printf(
"%c ", board[i][j]);
-
}
-
printf(
"\n");
-
}
-
printf(
"--------扫雷--------\n");
-
}
布置雷的函数实现:
利用生成随机数的库函数来让电脑随机放置雷,并且放置在符合所设置的坐标,如果生成的随机数相同则会重新生成随机数
-
void Set_mine(char mine[ROWS][COLS], int row, int col)//布置雷
-
{
-
//布置雷的个数
-
int count = MINE_COUNT;
-
while (count)
-
{
-
int x = rand() % row +
1;
-
int y = rand() % col +
1;
-
if (mine[x][y] ==
'0')
-
{
-
mine[x][y] =
'1';
-
count--;
-
}
-
}
-
}
排查雷函数的实现:
首先需要进行判断输入的坐标是否符合合法性,然后再判断该坐标是否被排查过,在判断是否被炸死,如果该坐标不是雷则继续排查。
排查时进行调用递归展开函数,如果排查的坐标周围没有雷,则进行递归展开。递归展开时要进行边界条件判断,防止数组越界。如果该坐标周围没有雷则进行设置为空格。再判断没有排查过的才进行递归展开排查,防止死递归
-
void Spread(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)//递归展开
-
{
-
int n =
get_mine_count(mine, x, y);
-
//边界条件,防止数组越界
-
if (x >=
1 && x <= ROW && y >=
1 && y <= COL)
-
{
-
if (n ==
0)
//需要展开
-
{
-
show[x][y] =
' ';
//该点周围没有雷就设置为空格
-
for (
int i = x -
1; i <= x +
1; i++) {
-
for (
int j = y -
1; j <= y +
1; j++) {
-
if (show[i][j] ==
'*')
//为*则为没有排查过的,可以展开,防止死递归
-
{
-
Spread(mine, show, i, j);
-
}
-
}
-
}
-
}
-
else {
-
show[x][y] = n +
'0';
//字符转为数字
-
}
-
}
-
}
-
-
void Fine_mine(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 - MINE_COUNT)
-
{
-
printf(
"请输入要排查的坐标:>");
-
scanf(
"%d %d", &x, &y);
-
if (x >=
1 && x <= row && y >=
1 && y <= col)
-
{
-
if (show[x][y] !=
'*')
-
{
-
printf(
"该坐标已经被排查,请重新输入\n");
-
continue;
-
}
-
if (mine[x][y] ==
'1')
-
{
-
printf(
"很遗憾,您被炸死了\n");
-
DisplayBoard(mine, ROW, COL);
-
break;
-
}
-
else
-
{
-
Spread(mine, show, x, y);
-
DisplayBoard(show, ROW, COL);
-
win++;
-
}
-
}
-
else
-
{
-
printf(
"坐标非法,请重新输入\n");
-
}
-
-
}
-
if (win == row * col - MINE_COUNT)
-
{
-
printf(
"恭喜你,排雷成功\n");
-
DisplayBoard(mine, ROW, COL);
-
}
-
}
完整源代码:
game1.c
-
#define _CRT_SECURE_NO_WARNINGS 1
-
#include"game1.h"
-
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)//初始化棋盘
-
{
-
int i =
0;
-
for (i =
0; i < rows; i++)
-
{
-
int j =
0;
-
for (j =
0; j < cols; j++)
-
{
-
board[i][j] = set;
-
}
-
}
-
}
-
void DisplayBoard(char board[ROWS][COLS], int row, int col)//打印棋盘
-
{
-
printf(
"--------扫雷--------\n");
-
for (
int j =
0; j <= col; j++)
-
{
-
printf(
"%d ", j);
-
}
-
printf(
"\n");
-
for (
int i =
1; i <= row; i++)
-
{
-
printf(
"%d ",i);
-
for (
int j =
1; j <= col; j++)
-
{
-
printf(
"%c ", board[i][j]);
-
}
-
printf(
"\n");
-
}
-
printf(
"--------扫雷--------\n");
-
}
-
void Set_mine(char mine[ROWS][COLS], int row, int col)//布置雷
-
{
-
//布置雷的个数
-
int count = MINE_COUNT;
-
while (count)
-
{
-
int x =
rand() % row +
1;
-
int y =
rand() % col +
1;
-
if (mine[x][y] ==
'0')
-
{
-
mine[x][y] =
'1';
-
count--;
-
}
-
}
-
}
-
int get_mine_count(char mine[ROWS][COLS], int x, int y)
-
{
-
return 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';
-
}
-
void Spread(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)//递归展开
-
{
-
int n =
get_mine_count(mine, x, y);
-
//边界条件,防止数组越界
-
if (x >=
1 && x <= ROW && y >=
1 && y <= COL)
-
{
-
if (n ==
0)
//需要展开
-
{
-
show[x][y] =
' ';
//该点周围没有雷就设置为空格
-
for (
int i = x -
1; i <= x +
1; i++) {
-
for (
int j = y -
1; j <= y +
1; j++) {
-
if (show[i][j] ==
'*')
//为*则为没有排查过的,可以展开,防止死递归
-
{
-
Spread(mine, show, i, j);
-
}
-
}
-
}
-
}
-
else {
-
show[x][y] = n +
'0';
//字符转为数字
-
}
-
}
-
}
-
-
void Fine_mine(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 - MINE_COUNT)
-
{
-
printf(
"请输入要排查的坐标:>");
-
scanf(
"%d %d", &x, &y);
-
if (x >=
1 && x <= row && y >=
1 && y <= col)
-
{
-
if (show[x][y] !=
'*')
-
{
-
printf(
"该坐标已经被排查,请重新输入\n");
-
continue;
-
}
-
if (mine[x][y] ==
'1')
-
{
-
printf(
"很遗憾,您被炸死了\n");
-
DisplayBoard(mine, ROW, COL);
-
break;
-
}
-
else
-
{
-
Spread(mine, show, x, y);
-
DisplayBoard(show, ROW, COL);
-
win++;
-
}
-
}
-
else
-
{
-
printf(
"坐标非法,请重新输入\n");
-
}
-
-
}
-
if (win == row * col - MINE_COUNT)
-
{
-
printf(
"恭喜你,排雷成功\n");
-
DisplayBoard(mine, ROW, COL);
-
}
-
}
text.c
-
#include"game1.h"
-
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);
-
Set_mine(mine, ROW, COL);
-
Fine_mine(mine,show, ROW, COL);
-
}
-
void menu()
-
{
-
printf(
"************************************\n");
-
printf(
"******* 1. play ******\n");
-
printf(
"******* 0. exit ******\n");
-
printf(
"************************************\n");
-
}
-
void test()
-
{
-
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);
-
}
-
int main()
-
{
-
test();
-
return
0;
-
}
game1.h
-
#define _CRT_SECURE_NO_WARNINGS 1
-
#include<stdio.h>
-
#include<stdlib.h>
-
#include<time.h>
-
#define ROW 9
-
#define COL 9
-
#define ROWS ROW+2
-
#define COLS COL+2
-
#define MINE_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 Set_mine(char mine[ROWS][COLS], int row, int col);
//布置雷
-
void Fine_mine(char mine [ROWS][COLS],char show[ROWS][COLS], int row, int col);
//排查雷
转载:https://blog.csdn.net/VHhhbb/article/details/128515582