前言
这篇博客教你如何用C语言实现 扫雷
一、三个文件
我们需要创建三个文件一个game.h头文件,game.c以及源.c文件,这三个文件会放到文末。
game.h: 对一些函数声明,以及宏定义。
game.c:主要存放扫雷游戏的主体函数。
源.h:主要存放主函数。
二、代码
1.主函数
关于main()函数,我们主要就是进行一个游戏开始交互,以及游戏的多次游玩,以及退出。还有菜单的打印。代码如下:
int main()
{
srand((unsigned int)time(NULL));
int n = 0;
do
{
menu();
printf("请选择:>");
scanf("%d", &n);
switch (n)
{
case 1:
game();
break;
case 0:
break;
default:
printf("输入错误,请重新选择!\n");
break;
}
} while (n);
return 0;
}
2.game()函数
game()函数里面会调用到很多函数,这些函数都是游戏的主体函数。
put():用于初始化雷盘
lei():用于随机在雷盘上布雷
print():用于打印雷盘
find():用于玩家扫雷
menu()
{
printf("*****************************\n");
printf("******* 1.play ********\n");
printf("******* 0.exit ********\n");
printf("*****************************\n");
}
void game()
{
char mine_board[ROWS][COLS];
char show_board[ROWS][COLS];
put(mine_board, ROWS, COLS, '0');
put(show_board, ROWS, COLS, '*');
lei(mine_board, ROW, COL);
system("cls");
//print(mine_board, ROW, COL);
print(show_board, ROW, COL);
find(mine_board, show_board, ROW, COL);
}
这里我们用了两个数组来存这个数据,mine_board这个数组用于存雷,show_board用于显示给玩家的雷盘,这样设计的原因是一个雷盘不易操作,很容易混淆。
3.初始化、布雷、打印雷盘
初始化就只要将数组首地址传到put()函数中,然后赋予你想要的符号就行了。
布雷也需要数组的首地址,但是这里还需要生成两个随机值,所以就有需要用到我们rand()函数以及srand()函数还有time()时间戳了。
打印雷盘只需要for循环就可以了,不过我们不能单纯的输出雷盘的数据,我们还得给玩家搞个坐标出来这样玩家就能有更好的游戏体验啦!
代码如下
void put(char board[ROWS][COLS], int rows, int cols, char set)
{
for (int i = 0; i < rows; i++)
for (int j = 0; j < cols; j++)
board[i][j] = set;
}
void lei(char board[ROWS][COLS], int row, int col)
{
int count = mine;
while (count)
{
int i = rand() % row + 1;
int j = rand() % col + 1;
if (board[i][j] == '0')
{
board[i][j] = '1';
count--;
}
}
}
void print(char board[ROWS][COLS], int row, int col)
{
for (int i = 0; i <= row; i++)
printf("%d ", i);
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");
}
}
4.排雷
我们排雷用到了主要在find()函数中进行,当然我们还要调用finds()函数以及 count_mine()函数。
fand()函数我们首先就是让玩家输入一个坐标当然我们要判断一下是否合理,如果合理就继续往下走,不然就重新输入。因为我们排雷会出现一片都没有雷的情况所以我们可以让他们都变成空格,不过我们这里就要用到finds()函数了。finds()函数可以判断输入坐标的周围有没有雷(当然这要调用count_mine()函数来实现)但如果周围八个都没有雷的就需要我们运用递归来实现了,我们让finds()函数调用自己,但是要设置限制条件以防再次调用到自己进入死循环。
好了大家肯定还是喜欢看代码,满足你们
int count_mine(char board[ROWS][COLS], int x, int y)
{
int count = 0;
for (int i = x - 1; i <= x + 1; i++)
{
for (int j = y - 1; j <= y + 1; j++)
{
if (board[i][j] == '1')
{
count++;
}
}
}
return count;
}
void finds(char m_board[ROWS][COLS], char s_board[ROWS][COLS], int row, int col, int x, int y, int* p)
{
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
int num = count_mine(m_board, x, y);
if (num == 0)
{
(*p)++;
s_board[x][y] = ' ';
int i = 0;
int j = 0;
for (i = x - 1; i <= x + 1; i++)
{
for (j = y - 1; j <= y + 1; j++)
{
if (s_board[i][j] == '*')
{
finds(m_board, s_board, row, col, i, j, p);
}
}
}
}
else
{
(*p)++;
s_board[x][y] = (num + '0');
}
}
}
void find(char m_board[ROWS][COLS], char s_board[ROWS][COLS], int row, int col)
{
int x = 0;
int y = 0;
int win = 0;
int* p = &win;
while (win < row * col - mine)
{
printf("请输入你要排查的坐标:>");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (m_board[x][y] == '1')
{
system("cls");
printf("\n 很遗憾,你被炸死了!\n");
print(m_board, row, col);
break;
}
else
{
if (s_board[x][y] != '*')
{
printf("这个坐标查过了,请重新输入!\n");
continue;
}
else
{
finds(m_board, s_board, row, col, x, y, p);
system("cls");
print(s_board, row, col);
}
}
}
else
{
printf("输入错误,请重新输入!\n");
}
}
if (win == row * col - mine)
{
system("cls");
printf("恭喜你,排雷成功!\n");
print(s_board, row, col);
return;
}
}
这里面有一些限制参数,如win,count,之类的主要是判断我们排雷成功的。
总结
代码我就放下面了,支持一下哦!(感谢三连)
//game.h
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<windows.h>
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define mine 10
void put(char board[ROWS][COLS], int rows, int cols, char set);
void lei(char board[ROWS][COLS], int row, int col);
void print(char board[ROWS][COLS], int row, int col);
void find(char m_board[ROWS][COLS], char s_board[ROWS][COLS], int row, int col);
void finds(char m_board[ROWS][COLS], char s_board[ROWS][COLS], int row, int col, int x, int y, int* p);
int count_mine(char borad[ROWS][COLS], int x, int y);
//game.c
#include"game.h"
void put(char board[ROWS][COLS], int rows, int cols, char set)
{
for (int i = 0; i < rows; i++)
for (int j = 0; j < cols; j++)
board[i][j] = set;
}
void lei(char board[ROWS][COLS], int row, int col)
{
int count = mine;
while (count)
{
int i = rand() % row + 1;
int j = rand() % col + 1;
if (board[i][j] == '0')
{
board[i][j] = '1';
count--;
}
}
}
void print(char board[ROWS][COLS], int row, int col)
{
for (int i = 0; i <= row; i++)
printf("%d ", i);
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");
}
}
int count_mine(char board[ROWS][COLS], int x, int y)
{
int count = 0;
for (int i = x - 1; i <= x + 1; i++)
{
for (int j = y - 1; j <= y + 1; j++)
{
if (board[i][j] == '1')
{
count++;
}
}
}
return count;
}
void finds(char m_board[ROWS][COLS], char s_board[ROWS][COLS], int row, int col, int x, int y, int* p)
{
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
int num = count_mine(m_board, x, y);
if (num == 0)
{
(*p)++;
s_board[x][y] = ' ';
int i = 0;
int j = 0;
for (i = x - 1; i <= x + 1; i++)
{
for (j = y - 1; j <= y + 1; j++)
{
if (s_board[i][j] == '*')
{
finds(m_board, s_board, row, col, i, j, p);
}
}
}
}
else
{
(*p)++;
s_board[x][y] = (num + '0');
}
}
}
void find(char m_board[ROWS][COLS], char s_board[ROWS][COLS], int row, int col)
{
int x = 0;
int y = 0;
int win = 0;
int* p = &win;
while (win < row * col - mine)
{
printf("请输入你要排查的坐标:>");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (m_board[x][y] == '1')
{
system("cls");
printf("\n 很遗憾,你被炸死了!\n");
print(m_board, row, col);
break;
}
else
{
if (s_board[x][y] != '*')
{
printf("这个坐标查过了,请重新输入!\n");
continue;
}
else
{
finds(m_board, s_board, row, col, x, y, p);
system("cls");
print(s_board, row, col);
}
}
}
else
{
printf("输入错误,请重新输入!\n");
}
}
if (win == row * col - mine)
{
system("cls");
printf("恭喜你,排雷成功!\n");
print(s_board, row, col);
return;
}
}