先贴一张效果图
文章图片
扫雷的基本思路 1.首先对棋盘初始化,并印出棋盘。
2.对棋盘进行埋雷。
3.输入坐标进行排雷。
4.编写函数统计当前位置周围的雷数,当周围8个位置都没有雷时进行递归展开。
5.统计棋盘中未展开的坐标数是否与雷数相等来判断输赢。
棋盘 首先对棋盘具体分析,应该创建两个棋盘,在一个棋盘中记录雷的位置,另一个棋盘打印出来给用户查看。
因为后面要统计当前位置周围的雷数,当位置在边角时,统计位置时会造成溢出,所以我们可以考虑把棋盘大上一圈,比如99的棋盘我们可以创建成1111的。
文章图片
如图所示,黑色框为打印给用户看到的棋盘,红色框里面的实际创建的大小,(上下左右均比棋盘大一个)这样就可以避免在统计图中红色部分是造成越界访问了。
初始化 对雷盘和棋盘进行初始化
void InitBoard(char board[ROWS][COLS], int row, int col, char val)
{
int i = 0;
for (int i = 0;
i < row;
i++)
{
int j = 0;
for (int j = 0;
j < col;
j++)
{
board[i][j] = val;
}
}
}
生成随机雷 在对棋盘初始化完成后,我们应该通过生成随机数来步骤雷,代码如下:
void CreateMine(char board[ROWS][COLS], int row, int col, int size)
{
int count = size;
while (count)
{
int x = rand() % row + 1;
int y = rand() % col + 1;
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (board[x][y] != '1')
{
board[x][y] = '1';
count--;
}
}
}
}
打印棋盘 完成布置雷后,接下来我们就可以打印出棋盘来了
void PrinBoard(char board[ROWS][COLS], int row, int col)
{
int i = 0;
printf("_________________________________\n");
for (i = 0;
i <= row;
i++)
printf(" %d", i);
printf("\n");
for (i = 1;
i <= row;
i++)
{
int j = 1;
printf("%2d ", i);
for (j = 1;
j <= col;
j++)
{
printf("%c ", board[i][j]);
}
printf("\n");
}
printf("_________________________________\n");
}
开始扫雷 通过对用户输入的坐标进行判断当前位置是否有雷,没有雷的话就要统计当前位置周围8个格子的雷数,如果周围8个位置没有雷,就要对周围8个格子进行递归展开。反之则被炸死,游戏结束。当每次统计完 判断当前状态是否胜利。
判断输赢
通过统计棋盘中未排查的坐标个数与雷数是否相等来判断是否输赢,当与雷数相同是,排雷成功游戏结束。
void PlayerMove(char show[ROWS][COLS], char mine[ROWS][COLS], int row, int col)
{
int x, y;
PrinBoard(show, ROW, COL);
while (1)
{
printf("输入需要排查的坐标>");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col && show[x][y] == '*')
{
if (mine[x][y] == '1')
{
printf("您被炸死了\n");
show[x][y] = '1';
PrinBoard(show, ROW, COL);
break;
}
else
{
Open(show, mine, x, y);
PrinBoard(show, ROW, COL);
}
}
else
{
printf("您当前输入的坐标不合法,请重新输入\n");
}
int i = 0, flag = 0;
for (i = 1;
i <= ROW;
i++)
{
int j = 0;
for (j = 1;
j <= COL;
j++)
{
if (show[i][j] == '*')
flag++;
}
}
if (flag == MINES)
{
printf("玩家获胜\n");
break;
}
}
}
展开函数
void Open(char show[ROWS][COLS], char mine[ROWS][COLS], int row, int col)
{
if (row > 0 && row <= ROW && col > 0 && col <= COL)
{
int count = Get_Mine_Count(mine, row, col);
if (count != 0)
show[row][col] = '0' + count;
else if (show[row][col] != ' ')
{
show[row][col] = ' ';
int i = 0;
for (int i = row - 1;
i <= row + 1;
i++)
{
int j = 0;
for (j = col - 1;
j <= col + 1;
j++)
{
Open(show, mine, i, j);
}
}
}
else
{
//show[row][col]!=' '递归停止
return ;
} }
}
统计周围雷数
int Get_Mine_Count(char board[ROWS][COLS], int row, int col)
{
int i = 0, count = 0;
for (i = row - 1;
i <= row + 1;
i++)
{
int j = 0;
for (j = col-1;
j <= col + 1;
j++)
{
if (board[i][j] == '1')
count++;
}
}
return count;
}
完整代码如下 text.c
#include"game.h"void menu()
{
printf("******************************\n");
printf("********1.play*********\n");
printf("********0.EXIT*********\n");
printf("******************************\n");
}void game()
{
int size = MINES;
char mine[ROWS][COLS];
char show[ROWS][COLS];
//初始化棋盘
InitBoard(mine, ROWS, COLS, '0');
InitBoard(show, ROWS, COLS, '*');
//布置雷
CreateMine(mine, ROW, COL, size);
PlayerMove(show, mine, 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 row, int col, char val)
{
int i = 0;
for (int i = 0;
i < row;
i++)
{
int j = 0;
for (int j = 0;
j < col;
j++)
{
board[i][j] = val;
}
}
}void PrinBoard(char board[ROWS][COLS], int row, int col)
{
int i = 0;
printf("_________________________________\n");
for (i = 0;
i <= row;
i++)
printf(" %d", i);
printf("\n");
for (i = 1;
i <= row;
i++)
{
int j = 1;
printf("%2d ", i);
for (j = 1;
j <= col;
j++)
{
printf("%c ", board[i][j]);
}
printf("\n");
}
printf("_________________________________\n");
}void CreateMine(char board[ROWS][COLS], int row, int col, int size)
{
int count = size;
while (count)
{
int x = rand() % row + 1;
int y = rand() % col + 1;
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (board[x][y] != '1')
{
board[x][y] = '1';
count--;
}
}
}
}int Get_Mine_Count(char board[ROWS][COLS], int row, int col)
{
int i = 0, count = 0;
for (i = row - 1;
i <= row + 1;
i++)
{
int j = 0;
for (j = col-1;
j <= col + 1;
j++)
{
if (board[i][j] == '1')
count++;
}
}
return count;
}
void Open(char show[ROWS][COLS], char mine[ROWS][COLS], int row, int col)
{
if (row > 0 && row <= ROW && col > 0 && col <= COL)
{
int count = Get_Mine_Count(mine, row, col);
if (count != 0)
show[row][col] = '0' + count;
else if (show[row][col] != ' ')
{
show[row][col] = ' ';
int i = 0;
for (int i = row - 1;
i <= row + 1;
i++)
{
int j = 0;
for (j = col - 1;
j <= col + 1;
j++)
{
Open(show, mine, i, j);
}
}
}
else
{
//show[row][col]!=' '递归停止
return ;
} }
}void PlayerMove(char show[ROWS][COLS], char mine[ROWS][COLS], int row, int col)
{
int x, y;
PrinBoard(show, ROW, COL);
while (1)
{
printf("输入需要排查的坐标>");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col && show[x][y] == '*')
{
if (mine[x][y] == '1')
{
printf("您被炸死了\n");
show[x][y] = '1';
PrinBoard(show, ROW, COL);
break;
}
else
{
Open(show, mine, x, y);
PrinBoard(show, ROW, COL);
}
}
else
{
printf("您当前输入的坐标不合法,请重新输入\n");
}
int i = 0, flag = 0;
for (i = 1;
i <= ROW;
i++)
{
int j = 0;
for (j = 1;
j <= COL;
j++)
{
if (show[i][j] == '*')
flag++;
}
}
if (flag == MINES)
{
printf("玩家获胜\n");
break;
}
}
}
【算法|C语言版扫雷(递归实现自动展开)】game.h
#pragma once#define_CRT_SECURE_NO_WARNINGS
#include
#include
#include
enum
{
ROW = 10,
COL = 10,
ROWS = ROW + 2,
COLS = COL + 2,
MINES = 5 //雷数
};
void InitBoard(char board[ROWS][COLS], int row, int col, char val);
void PrinBoard(char board[ROWS][COLS], int row, int col);
void CreateMine(char board[ROWS][COLS], int row, int col, int size);
void PlayerMove(char show[ROWS][COLS], char mine[ROWS][COLS], int row, int col);
int Get_Mine_Count(char board[ROWS][COLS], int row, int col);
void Open(char show[ROWS][COLS], char mine[ROWS][COLS], int row, int col);
推荐阅读
- 个人的小白成长经历|【濡白的C语言】初学者-从零开始-5(模块化设计——函数,传值和传址)
- 经验分享|Tic Tac Toe简单井字棋
- Java|【数据结构与算法】——必知必会的排序算法你会几种
- 数据结构与算法|数据结构与算法 | 用Java语言实现顺序表真的不难
- 程序人生|跳槽(内卷?2022金三银四下程序员的自我修养)
- python|Python数据可视化大杀器之地阶技法(matplotlib(含详细代码))
- python|python机器学习从入门到高级(超参数调整(含详细代码))
- 程序人生|一个30岁的程序员无比挣扎的故事,连躺平都是奢望
- 程序人生|作为程序员,如何开展自己的副业(月赚三万的真实故事)