栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C语言实现数字扫雷

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C语言实现数字扫雷

目录

一、打印菜单

二、游戏实现

三、头文件(sl.h)

四、函数实现(slhs.c)

1、棋盘设置

2、打印棋盘

3、布置雷区

4、排雷

a.计算周围雷的个数

b.递归排雷

c.判断胜利

d.执行

五、补充操作

1、标记雷区

2、取消标记

3、跳过第一次排雷被炸

4、定位光标与改换颜色

六、完整代码



话不所说,跟着来操作……

一、打印菜单
//菜单
void menu(){
	printf("********************************n");
	printf("****  1、play     0、exist  ****n");
	printf("********************************n");
}
//菜单选择
void test(){
	int input;
	srand((unsigned)time(NULL));//随机埋雷需用
	do{
		menu();
		printf("请选择:>");
		scanf("%d", &input);
		switch (input){
		case 1:game();
			break;
		case 0:printf("欢迎下次再玩n");
			break;
		default:printf("选择错误,请重新选择n");
			break;
		}
	} while (input);
}

二、游戏实现

分为两个棋盘,一个用来显示,一个用来存储扫雷信息

void game(){
	//雷的信息存储
	//1.布置好的雷的信息
	char mine[ROWS][COLS] = { 0 };
	//2.排查出的雷的信息
	char show[ROWS][COLS] = { 0 };
	//初始化
	InitBoard(mine, ROWS, COLS,'0');
	InitBoard(show, ROWS, COLS, '*');
	//打印棋盘
	//DisplayBoard(mine, ROW, COL);
	DisplayBoard(show, ROW, COL);
	//布置雷
	SetMine(mine, ROW, COL);
//	DisplayBoard(mine, ROW, COL);//显示埋雷位置
	//扫雷
	//DisplayBoard(mine, ROW, COL);
	FineMine(mine, show, ROW, COL);
}

三、头文件(sl.h)

为了方便,显得不那么乱,我们把所有的头文件、所定义函数、棋盘大小放在头文件中

#define ROW 9
#define COL 9    //棋盘大小9x9
#define ROWS ROW+2
#define COLS COL+2    //幕后棋盘实际要四周扩一格
#define EASY_COUNT 10  //埋雷个数


#include 
#include 
#include 

void InitBoard(char board[ROWS][COLS],int rows,int cols,char set);
void DisplayBoard(char board[ROWS][COLS], int row, int col);
void SetMine(char board[ROWS][COLS], int row, int col);
void FineMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);

四、函数实现(slhs.c)

1、棋盘设置
//棋盘设置
void InitBoard(char board[ROWS][COLS], int rows, int cols,char set){
	int i, j;
	for (i = 0; i < rows; i++){
		for (j = 0; j < cols; j++){
			board[i][j] = set;
		}
	}
}

2、打印棋盘
//打印棋盘
void DisplayBoard(char board[ROWS][COLS], int row, int col){
	int i, j;
	//打印列号
	for (i = 0; i <= col; i++){
		printf("%d ", i);
	}
	printf("n");
	for (i = 1; i <= row; i++){
		printf("%d ", i);
		for (j = 1; j <= col; j++){
			printf("%c ", board[i][j]);
		}
		printf("n");
	}
}

3、布置雷区
//布置雷
void SetMine(char board[ROWS][COLS], int row, int col){
	int count = EASY_COUNT;
	while (count){
		int x = rand() % row + 1;//1-9
		int y = rand() % col + 1;
		if (board[x][y] == '0'){
			board[x][y] = '1';
			count--;
		}
	}
}

4、排雷

a.计算周围雷的个数
int get_mine_count(char mine[ROWS][COLS], int x, int y){
	return 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] + mine[x - 1][y + 1] - 8 * '0';
}

b.递归排雷
void Rd(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y){
	//判断坐标是否合法
	if (x==0 || y ==0 || x==ROWS-1 || y == COLS-1) return;
	//判断是否已被排出
	if (show[x][y] != '*') return;
	int count = get_mine_count(mine, x, y);
	if (count > 0){
		show[x][y] = count + '0';
		return;
	}
	else if (count == 0){
		show[x][y] = '0';
		Rd(mine, show, x, y - 1);
		Rd(mine, show, x, y + 1);
		Rd(mine, show, x + 1, y - 1);
		Rd(mine, show, x + 1, y + 1);
		Rd(mine, show, x + 1, y);
		Rd(mine, show, x - 1, y - 1);
		Rd(mine, show, x - 1, y);
		Rd(mine, show, x - 1, y + 1);
	}
}

c.判断胜利
int Victory(char show[ROWS][COLS],int row, int col){
	int i,j;
	int win = 0;
	for(i=1;i<=row;i++){
		for(j=1;j<=col;j++){
			if(show[i][j] == '*'){
				win++;
			}
		}
	}
	return win;
}

d.执行
void FineMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col){
	int x, y;
	size_t flag_count = 0;
	int win = 0;
	while (1){
		printf("请输入坐标并用空格隔开:>");
		scanf("%d%d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col){
			//坐标合法
			//踩雷
			if (mine[x][y] == '1'){
				printf("很遗憾,游戏失败!n");
				puts("n雷阵如下:n");
				DisplayBoard(mine, row, col);
				break;
			}
			//不是雷
			else{
				Rd(mine, show, x, y);
				DisplayBoard(show, row, col);
			}
		}
		else{
			printf("坐标非法,请重新输入!n");
		}
		win = Victory(show,row,col);
		if(win ==  EASY_COUNT) break;
	}
	if (win == EASY_COUNT){
		printf("恭喜,通关成功nn");
		printf("雷阵如下:n");
		DisplayBoard(mine, row, col);
	}
}

五、补充操作

本程序未添加这几项功能,感兴趣的盆友可自行发挥,添加……

当然,若博主后期比较闲的话也可能来优化

1、标记雷区
int Flagmine(char show[ROWS][COLS], int row, int col, size_t flag){
	int x = 0, y = 0;
	if (flag == EASY_COUNT){
		printf("标记的雷与实际存在的雷数量相等,无法标记n");
		return 0;
	}
	printf("请输入你要标记的坐标:> ");
	scanf("%d %d", &x, &y);
	//判断坐标的合法性
	if (x >= 1 && x <= row && y >= 1 && y <= col){
		//判断是否已被确认为雷
		if (show[x][y] == '*'){
			show[x][y] = '!';//以!作为标记
			flag++;
		}
		else{
			printf("该坐标不可能是雷,请重新输入!n");
		}
	}
	else{
		printf("该坐标不合法,请重新输入!n");
	}
	return flag;
}

2、取消标记
int Cancelflag(char show[ROWS][COLS], int row, int col, int flag_count){
	int x = 0, y = 0;
	printf("请输入需要取消的坐标:> ");
	scanf("%d %d", &x, &y);
	//判断坐标是否合法
	if (x >= 1 && x <= row && y >= 1 && y <= col){
		//判断是否被标记过
		if (show[x][y] == '!'){
			show[x][y] = '*';
			flag_count--;
		}
		else
			printf("该位置未被标记过,无需取消标记n");
	}
	else
		printf("该坐标不合法,请重新输入!n");
	return flag_count;
}

3、跳过第一次排雷被炸
void Change(char mine[ROWS][COLS],int row, int col,int x,int y){
	x=rand()%row;
	y=rand()%col;
	mine[x][y]='1';
	printf("第一次就踩雷了哟,请重新选择!n");
}

4、定位光标与改换颜色

此两项操作请阅读孤的“迷宫小游戏”C语言实现初级小迷宫_一段路的博客-CSDN博客_c语言制作小迷宫


六、完整代码
//sl.h

#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define EASY_COUNT 10


#include 
#include 
#include 

void InitBoard(char board[ROWS][COLS],int rows,int cols,char set);
void DisplayBoard(char board[ROWS][COLS], int row, int col);
void SetMine(char board[ROWS][COLS], int row, int col);
void FineMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);

//sl.c
void menu(){
	printf("********************************n");
	printf("****  1、play     0、exist  ****n");
	printf("********************************n");
}
void game(){
	//雷的信息存储
	//1.布置好的雷的信息
	char mine[ROWS][COLS] = { 0 };
	//2.排查出的雷的信息
	char show[ROWS][COLS] = { 0 };
	//初始化
	InitBoard(mine, ROWS, COLS,'0');
	InitBoard(show, ROWS, COLS, '*');
	//打印棋盘
	//DisplayBoard(mine, ROW, COL);
	DisplayBoard(show, ROW, COL);
	//布置雷
	SetMine(mine, ROW, COL);
	//DisplayBoard(mine, ROW, COL);
	//扫雷
	//DisplayBoard(mine, ROW, COL);
	FineMine(mine, show, ROW, COL);
}
//执行
void test(){
	int input;
	srand((unsigned)time(NULL));
	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;
}

//slhs.c
//棋盘设置
void InitBoard(char board[ROWS][COLS], int rows, int cols,char set){
	int i, j;
	for (i = 0; i < rows; i++){
		for (j = 0; j < cols; j++){
			board[i][j] = set;
		}
	}
}
//打印棋盘
void DisplayBoard(char board[ROWS][COLS], int row, int col){
	int i, j;
	//打印列号
	for (i = 0; i <= col; i++){
		printf("%d ", i);
	}
	printf("n");
	for (i = 1; i <= row; i++){
		printf("%d ", i);
		for (j = 1; j <= col; j++){
			printf("%c ", board[i][j]);
		}
		printf("n");
	}
}
//布置雷
void SetMine(char board[ROWS][COLS], int row, int col){
	int count = EASY_COUNT;
	while (count){
		int x = rand() % row + 1;//1-9
		int y = rand() % col + 1;
		if (board[x][y] == '0'){
			board[x][y] = '1';
			count--;
		}
	}
}
//排雷
int get_mine_count(char mine[ROWS][COLS], int x, int y){
	return 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] + mine[x - 1][y + 1] - 8 * '0';
}
//递归
void Rd(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y){
	//判断坐标是否合法
	if (x==0 || y ==0 || x==ROWS-1 || y == COLS-1) return;
	//判断是否已被排出
	if (show[x][y] != '*') return;
	int count = get_mine_count(mine, x, y);
	if (count > 0){
		show[x][y] = count + '0';
		return;
	}
	else if (count == 0){
		show[x][y] = '0';
		Rd(mine, show, x, y - 1);
		Rd(mine, show, x, y + 1);
		Rd(mine, show, x + 1, y - 1);
		Rd(mine, show, x + 1, y + 1);
		Rd(mine, show, x + 1, y);
		Rd(mine, show, x - 1, y - 1);
		Rd(mine, show, x - 1, y);
		Rd(mine, show, x - 1, y + 1);
	}
}
//标记雷
int Flagmine(char show[ROWS][COLS], int row, int col, size_t flag){
	int x = 0, y = 0;
	if (flag == EASY_COUNT){
		printf("标记的雷与实际存在的雷数量相等,无法标记n");
		return 0;
	}
	printf("请输入你要标记的坐标:> ");
	scanf("%d %d", &x, &y);
	//判断坐标的合法性
	if (x >= 1 && x <= row && y >= 1 && y <= col){
		//判断是否已被确认为雷
		if (show[x][y] == '*'){
			show[x][y] = '!';//以!作为标记
			flag++;
		}
		else{
			printf("该坐标不可能是雷,请重新输入!n");
		}
	}
	else{
		printf("该坐标不合法,请重新输入!n");
	}
	return flag;
}
//取消标记
int Cancelflag(char show[ROWS][COLS], int row, int col, int flag_count){
	int x = 0, y = 0;
	printf("请输入需要取消的坐标:> ");
	scanf("%d %d", &x, &y);
	//判断坐标是否合法
	if (x >= 1 && x <= row && y >= 1 && y <= col){
		//判断是否被标记过
		if (show[x][y] == '!'){
			show[x][y] = '*';
			flag_count--;
		}
		else
			printf("该位置未被标记过,无需取消标记n");
	}
	else
		printf("该坐标不合法,请重新输入!n");
	return flag_count;
}
//判断胜利
int Victory(char show[ROWS][COLS],int row, int col){
	int i,j;
	int win = 0;
	for(i=1;i<=row;i++){
		for(j=1;j<=col;j++){
			if(show[i][j] == '*'){
				win++;
			}
		}
	}
	return win;
}
void FineMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col){
	int x, y;
	size_t flag_count = 0;
	int win = 0;
	while (1){
		printf("请输入坐标并用空格隔开:>");
		scanf("%d%d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col){
			//坐标合法
			//踩雷
			if (mine[x][y] == '1'){
				printf("很遗憾,游戏失败!n");
				puts("n雷阵如下:n");
				DisplayBoard(mine, row, col);
				break;
			}
			//不是雷
			else{
				Rd(mine, show, x, y);
				DisplayBoard(show, row, col);
			}
		}
		else{
			printf("坐标非法,请重新输入!n");
		}
		win = Victory(show,row,col);
		if(win ==  EASY_COUNT) break;
	}
	if (win == EASY_COUNT){
		printf("恭喜,通关成功nn");
		printf("雷阵如下:n");
		DisplayBoard(mine, row, col);
	}
}

         


                     

 


不足之处,请多多指教,欢迎留言……

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/867235.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号