c语言实现初阶版扫雷游戏

一、基本思路

代码由三部分组成:game.h(头文件以及声明函数)、test.c(主函数以及调用game.c中的函数实现扫雷)、game.c(定义扫雷的4个函数)。

要实现扫雷的功能,game.c中应包含以下功能:①初始化棋盘;②打印棋盘;③布置雷;④排查雷及判断输赢;

在test.c中,首先要打印一个菜单供玩家选择,其次玩家在选择后要实现玩游戏或退出游戏。

二、test.c

在编写主函数时,我们想先在屏幕上输出一个菜单,玩家在看到后可以供玩家选择,写一个menu()函数,主函数调用打印菜单。menu函数

void menu()
{
	printf("########################\n");
	printf("###### 1.进入游戏 ######\n");
	printf("###### 0.退出游戏 ######\n");
	printf("########################\n");
}

在打印完菜单后由玩家选择,do while循环实现,内嵌switch。输入1,玩家进入游戏,调用game()函数,game()函数中有4个其他函数,实现扫雷的功能;输入0,退出循环,玩家退出游戏;输入其他数字,提示有误,重新输入。主函数针对第二行srand()放在后面解释):

int main()
{
	srand((unsigned int)time(NULL));
	int n;
	do {
		menu();
		printf("请玩家选择:> ");
		scanf("%d", &n);
		switch (n) {
		case 1:
			game();
			break;
		case 0:
			printf("玩家退出游戏");
			break;
		default:
			printf("玩家选择有误,请重新选择\n");
			break;
		}
	} while (n);
}

 game()函数设计思路:

可以将棋面想象成一个二维数组,放雷的为一个棋面,排查雷信息的为一个棋面,所以先定义两个二维数组,针对二维数组的行与列以及雷的个数,将其定义为常变量,方便对棋面以及游戏难易程度进行改动。在game()中调用了4个函数,先调用InitalBoard()函数初始化棋面,将布置雷的棋面,字符型二维数组赋值为'0';将雷的信息,字符型二维数组赋值为'*';再调用PrintfBoard()函数,打印雷的信息的棋面;再调用SetMine()函数,在布置雷的棋面上设置相应个数的雷;最后调用LookMine()函数,在打印雷信息的棋面上计算对应坐标周围雷的个数,并判断输赢。

void game()
{
	char a[ROWS][COLS];
	char b[ROWS][COLS];
	//初始化棋面
	InitalBoard(a, ROWS, COLS, '0');
	InitalBoard(b, ROWS, COLS, '*');
	//打印棋面
	//PrintfBoard(a, ROW, COL);   //打印布置好雷的棋面
	PrintfBoard(b, ROW, COL);   //打印雷的信息
	//布置雷
	SetMine(a, ROW, COL);
	//PrintfBoard(a, ROW, COL);   //打印布置好雷的棋面
	//排查雷信息
	LookMine(a, b, ROW, COL);
}

三、game.c

在game.c中主要是定义了InitalBoard()、PrintfBoard()、SetMine()、LookMine() 4个函数。

InitalBoard()函数

将棋面想象成二维数组,布置雷的棋面初始化为'0',显示雷信息的棋面初始化为'*',需要注意的是,在排查雷信息时,对于边界处的坐标,在统计时容易数组出界,所以我们初始化的棋面是在打印棋面上增大了一圈,例如:玩游戏的界面是9×9的,但是在初始化的时候是11×11,布置雷是在9×9棋面上,排查雷是在11×11棋面上,打印雷的信息是9×9的棋面。

void InitalBoard(char a[ROWS][COLS], int rows, int cols, char b)
{
	int i, j;
	for (i = 0; i < rows; i++) {
		for (j = 0; j < cols; j++)
			a[i][j] = b;
	}
}

 PrintfBoard()函数:

打印出初始化的雷信息棋面,元素全为'*',且打印出了每行每列的数字。

void PrintfBoard(char a[ROWS][COLS], int row, int col)
{
	printf("------ 棋面 ------\n");
	int i, j;
	for (j = 0; j <= col; j++) {
		printf("%d ", j);
	}
	printf("\n");
	for (i = 1; i <= row; i++) {
		printf("%d ", i);
		for (j = 1; j <= col; j++) {
			printf("%c ", a[i][j]);
		}
		printf("\n");
	}
}

SetMine()函数:

放置Mine个雷,范围为第一个二维数组中第1行到第ROW行,第1列到第COL列,如何在二维数组中随机产生雷?先创建rand()函数可以产生随机值,而在主函数中使用srand((unsigned int)time(NULL))可以保证每次进入游戏产生的随机值不同,为了使产生的随机值在二维数组范围内,可以使用rand()%row+1,产生1到row1之间的数。while循环判断雷的个数是否达到给定个数,在while循环中使用if语句判断是否重复放置雷。

void SetMine(char a[ROWS][COLS], int row, int col)
{
	int i, j;
	int count = 0;
	while (count < Mine) {
		i = rand() % row + 1;   //产生1到row的随机数
		j = rand() % col + 1;   //产生1到col的随机数
		if (a[i][j] == '0') {
			a[i][j] = '1';
			count++;
		}
	}
}

LookMine()函数

布置好雷后,在第一个二维数组中输入坐标,当输入坐标有误时,会要求玩家重新输入坐标。若刚好开中雷,则游戏结束;若没开中雷,则统计其周围一圈8个元素雷的个数,若有雷,则变量count加1,最终将count变量转为字符,填入对应坐标的第二个数组。当统计雷的信息的元素等于二维数组(行×列-雷的个数)时,游戏结束,玩家取得胜利。

void LookMine(char a[ROWS][COLS], char b[ROWS][COLS], int row, int col)
{
	int x, y;
	int count = 0;
	int k = 0;
	while (k < (row * col) - Mine)
	{
		printf("请输入坐标,用空格隔开:");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (a[x][y] == '1')
			{
				printf("很遗憾你开中了雷,游戏结束\n");
				PrintfBoard(a, ROW, COL);
				break;
			}
			else
			{
				int i, j;
				for (i = x - 1; i <= x + 1; i++) {
					for (j = y - 1; j <= y + 1; j++) {
						if (a[i][j] == '1')
							count++;
					}
				}
				b[x][y] = count + '0';
				count = 0;
				k++;
				PrintfBoard(b, ROW, COL);   //打印雷的信息

			}
		}
		else
			printf("输入坐标有误,需重新输入");

	}
	if (k == (row * col) - Mine)
		printf("恭喜你,游戏成功!!!\n");
}

四、game.h 

 game.h中主要放需要用到的头文件以及game.c中4个函数的声明,c语言的标志头文件#include<stdio.h>,调用rand()函数用到头文件#include<stdlib.h>,在主函数srand()函数中调用time()函数,用到头文件#include<time.h>,定义棋盘行数、列数以及雷的个数为常变量,用到头文件#define

#pragma once
#include<stdio.h>
#include <stdlib.h>;
#include <time.h>;
#define COL 9
#define ROW 9
#define COLS COL+1
#define ROWS ROW+1
#define Mine 10
//初始化棋盘函数声明
void InitalBoard(char a[ROWS][COLS], int rows, int cols, char b);
//打印棋盘函数声明
void PrintfBoard(char a[ROWS][COLS], int row, int col);
//布置雷函数声明
void SetMine(char a[ROWS][COLS], int row, int col);
//排查雷信息函数
void LookMine(char a[ROWS][COLS], char b[ROWS][COLS], int row, int col);

五、完整代码

game.h:

#pragma once
#include<stdio.h>
#include <stdlib.h>;
#include <time.h>;
#define COL 9
#define ROW 9
#define COLS COL+1
#define ROWS ROW+1
#define Mine 10
//初始化棋盘函数声明
void InitalBoard(char a[ROWS][COLS], int rows, int cols, char b);
//打印棋盘函数声明
void PrintfBoard(char a[ROWS][COLS], int row, int col);
//布置雷函数声明
void SetMine(char a[ROWS][COLS], int row, int col);
//排查雷信息函数
void LookMine(char a[ROWS][COLS], char b[ROWS][COLS], int row, int col);

test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
void menu()
{
	printf("########################\n");
	printf("###### 1.进入游戏 ######\n");
	printf("###### 0.退出游戏 ######\n");
	printf("########################\n");
}
void game()
{
	char a[ROWS][COLS];
	char b[ROWS][COLS];
	//初始化棋面
	InitalBoard(a, ROWS, COLS, '0');
	InitalBoard(b, ROWS, COLS, '*');
	//打印棋面
	//PrintfBoard(a, ROW, COL);   //打印布置好雷的棋面
	PrintfBoard(b, ROW, COL);   //打印雷的信息
	//布置雷
	SetMine(a, ROW, COL);
	//PrintfBoard(a, ROW, COL);   //打印布置好雷的棋面
	//排查雷信息
	LookMine(a, b, ROW, COL);
}
int main()
{
	srand((unsigned int)time(NULL));
	int n;
	do {
		menu();
		printf("请玩家选择:> ");
		scanf("%d", &n);
		switch (n) {
		case 1:
			game();
			break;
		case 0:
			printf("玩家退出游戏");
			break;
		default:
			printf("玩家选择有误,请重新选择\n");
			break;
		}
	} while (n);
}

game.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
//初始化棋盘函数定义
void InitalBoard(char a[ROWS][COLS], int rows, int cols, char b)
{
	int i, j;
	for (i = 0; i < rows; i++) {
		for (j = 0; j < cols; j++)
			a[i][j] = b;
	}
}
//打印棋盘函数定义
void PrintfBoard(char a[ROWS][COLS], int row, int col)
{
	printf("------ 棋面 ------\n");
	int i, j;
	for (j = 0; j <= col; j++) {
		printf("%d ", j);
	}
	printf("\n");
	for (i = 1; i <= row; i++) {
		printf("%d ", i);
		for (j = 1; j <= col; j++) {
			printf("%c ", a[i][j]);
		}
		printf("\n");
	}
}
//放雷函数定义
void SetMine(char a[ROWS][COLS], int row, int col)
{
	int i, j;
	int count = 0;
	while (count < Mine) {
		i = rand() % row + 1;   //产生1到row的随机数
		j = rand() % col + 1;   //产生1到col的随机数
		if (a[i][j] == '0') {
			a[i][j] = '1';
			count++;
		}
	}
}
//排查雷信息函数定义
void LookMine(char a[ROWS][COLS], char b[ROWS][COLS], int row, int col)
{
	int x, y;
	int count = 0;
	int k = 0;
	while (k < (row * col) - Mine)
	{
		printf("请输入坐标,用空格隔开:");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (a[x][y] == '1')
			{
				printf("很遗憾你开中了雷,游戏结束\n");
				PrintfBoard(a, ROW, COL);
				break;
			}
			else
			{
				int i, j;
				for (i = x - 1; i <= x + 1; i++) {
					for (j = y - 1; j <= y + 1; j++) {
						if (a[i][j] == '1')
							count++;
					}
				}
				b[x][y] = count + '0';
				count = 0;
				k++;
				PrintfBoard(b, ROW, COL);   //打印雷的信息

			}
		}
		else
			printf("输入坐标有误,需重新输入");

	}
	if (k == (row * col) - Mine)
		printf("恭喜你,游戏成功!!!\n");
}

六、运行结果 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
好的,下面是一个简单的C语言扫雷游戏实现步骤: 1. 定义游戏所需要的变量,如雷区大小、雷数、游戏状态、扫雷数组等。 ```c int row, col; // 雷区的行数和列数 int total_mines; // 雷区中的雷数 int game_state; // 游戏状态,0表示游戏正在进行,1表示游戏胜利,2表示游戏失败 int mine_field[MAX_ROW][MAX_COL]; // 扫雷数组,0表示没有雷,1表示有雷 ``` 2. 初始化雷区,将扫雷数组中的所有元素置为0,然后随机生成指定数量的雷,并将它们的位置标记在扫雷数组中。 ```c void init_mine_field() { int i, j, count = 0; // 将扫雷数组中的所有元素置为0 for (i = 0; i < row; i++) { for (j = 0; j < col; j++) { mine_field[i][j] = 0; } } // 随机生成指定数量的雷,并将它们的位置标记在扫雷数组中 while (count < total_mines) { int x = rand() % row; int y = rand() % col; if (mine_field[x][y] == 0) { mine_field[x][y] = 1; count++; } } } ``` 3. 实现用于显示雷区的函数,根据扫雷数组中的元素值,在控制台上输出相应的字符,如“#”表示未翻开的格子,“*”表示有雷的格子,“0”~“8”表示周围的雷数。 ```c void display_mine_field() { int i, j; for (i = 0; i < row; i++) { for (j = 0; j < col; j++) { if (mine_field[i][j] == 0) { printf("# "); } else if (mine_field[i][j] == 1) { printf("* "); } else { printf("%d ", mine_field[i][j] - 2); } } printf("\n"); } } ``` 4. 实现用于翻开指定位置格子的函数,如果该位置有雷,则游戏失败;否则,统计周围的雷数并在扫雷数组中标记该位置的状态。 ```c void open_cell(int x, int y) { if (mine_field[x][y] == 1) { game_state = 2; // 游戏失败 printf("Game over!\n"); } else { int i, j, count = 0; // 统计周围的雷数 for (i = x - 1; i <= x + 1; i++) { for (j = y - 1; j <= y + 1; j++) { if (i >= 0 && i < row && j >= 0 && j < col && mine_field[i][j] == 1) { count++; } } } // 标记该位置的状态 mine_field[x][y] = count + 2; if (count == 0) { // 如果周围没有雷,则递归翻开周围的格子 for (i = x - 1; i <= x + 1; i++) { for (j = y - 1; j <= y + 1; j++) { if (i >= 0 && i < row && j >= 0 && j < col && mine_field[i][j] == 0) { open_cell(i, j); } } } } } } ``` 5. 主函数中首先初始化游戏变量,然后循环进行游戏,直到游戏结束为止。在每一轮循环中,先显示当前雷区的状态,然后读取玩家输入并翻开相应的格子。 ```c int main() { srand(time(NULL)); // 初始化随机种子 printf("Please enter row, col and total mines: "); scanf("%d %d %d", &row, &col, &total_mines); init_mine_field(); // 初始化雷区 game_state = 0; // 游戏正在进行 while (game_state == 0) { display_mine_field(); // 显示当前雷区的状态 int x, y; printf("Please enter cell position: "); scanf("%d %d", &x, &y); open_cell(x, y); // 翻开指定位置的格子 } return 0; } ``` 以上是一个简单的C语言扫雷游戏实现示例,您可以根据自己的需求和喜好进行修改和完善。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ambition…

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值