c语言-------扫雷

c语言-------扫雷,第1张

文章目录
  • 游戏简介
    • 1. 前言
    • 2. 扫雷游戏规则:
  • 一、各功能函数
    • 1. 简易菜单
    • 2. 初始化扫雷界面
    • 3. 打印扫雷界面
    • 4. 布雷
    • 5. 标记
    • 6. 展开(爆炸式效果)
    • 7. 找雷
    • 8. 排雷
  • 二、完整代码
    • 1.game.h------游戏用到的函数
    • 2.test.c---------主逻辑
    • 3. game.c---------游戏的实现
  • 总结


游戏简介 1. 前言

游戏中需要两个数组,一个用于存放雷(不向玩家展示),另一个用于向用户展示游戏进程,即排雷情况.

2. 扫雷游戏规则:

从键盘输入你推测的非雷的坐标,如果该坐标为雷,恭喜您被炸,游戏失败
游戏失败后屏幕上打印出的棋盘中1表示该位置为雷,0表示该位置非雷
如果该坐标不是雷,屏幕上会显示出该坐标周围(上下左右)八个坐标中雷的个数,
玩家可根据屏幕上显示的雷的个数进行下一步排雷
当玩家将坐标中全部非雷坐标都找到,玩家获得胜利.
提示:共有十个雷(该数可在源代码的预处理字符EASYCOUNT自定义)

添加了标记和展开功能:
标记:可以标记已经确认的雷的位置
展开:输入一个坐标,若该坐标周围无雷, 可将该坐标周围无雷区域全部显示出来
game.h 头文件中是函数声明
game.c 源文件里面是函数定义和调用
test.c 源文件里面是函数调用

一、各功能函数 1. 简易菜单
void menu() {
	printf("*****************\n");
	printf("**** 1. play ****\n");
	printf("**** 0. exit ****\n");
	printf("*****************\n");
}
2. 初始化扫雷界面
//初始化
void Initboard(char board[ROWS][COLS], int rows, int cols, char ret) {
	int i = 0, j = 0;
	for (i = 0; i < rows; i++) {
		for (j = 0; j < cols; j++) {
			board[i][j] = ret;
		}
	}
}
3. 打印扫雷界面
void DisplayBoard(char board[ROWS][COLS], int row, int col) {
	int i = 0, j = 0;
	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 ", board[i][j]);
		}
		printf("\n");
	}
}

4. 布雷

布雷用到了随机数的生成,需要包含头文件stdlib.h和time.h

//布雷
void Getthunder(char board[ROWS][COLS], int row, int col) {
	int count = EASYCOUNT;
	while (count) {
		int i = rand() % 9 + 1;
		int j = rand() % 9 + 1;
		if (board[i][j] == '0') {
			board[i][j] = '1';
			count--;
		}
	}
}

有雷处为1, 非雷处为0,此界面不向玩家展示

5. 标记

如果有玩家已确认的雷, 可以将其标记

6. 展开(爆炸式效果)

展开以函数递归实现
输入一个坐标,若该坐标周围无雷, 可将该坐标周围无雷区域全部显示出来
这里我们将地雷数设置为1,方便查看爆炸效果
可以看到非雷区将全部以空格形式展示

void Spr_board(char thunder[ROWS][COLS], char show[ROWS][COLS], int x, int y) {
	
	if (x >= 1 && x <= 9 && y >= 1 && y <= 9) {
		int i = -1, j = -1;
		for (i = -1; i < 2; i++) {
			for (j = -1; j < 2; j++) {
				if (thunder[x + i][y + j] == '0') {
					if (show[x + i][y + j] == '*') {
						show[x + i][y + j] = get_thunder_count(thunder, x + i, y + j) + '0';
						if ('0' == show[x + i][y + j]) {
							show[x][y] = ' ';
							show[x +i][y + j] = ' ';
							//show[x][y] = ' ';
							//DisplayBoard(thunder, ROW, COL);
							//DisplayBoard(show, ROW, COL);
							Spr_board(thunder, show, x + i, y + j);
						}
					}
				}
			}
		}
	}
}
7. 找雷
int get_thunder_count(char thunder[ROWS][COLS], int x, int y) {
	return (thunder[x - 1][y - 1] + thunder[x - 1][y] + thunder[x - 1][y + 1] +
		thunder[x][y - 1] + thunder[x][y + 1] +
		thunder[x + 1][y - 1] + thunder[x + 1][y] + thunder[x + 1][y + 1] - 8 * '0');
}

这里用加减的方法实现了由字符到数字的转变
将该值加’0’就又能将数字转换为字符,这种方法还是第一次见.

8. 排雷
//排雷
void FindBoard(char thunder[ROWS][COLS], char show[ROWS][COLS], int row, int col) {
	int x = 0, y = 0;
	int win = 0;
	char b = '0';
	while (win < ROW * COL - EASYCOUNT) {
		int x1 = 0, y1 = 0;
		do {
			printf("是否要标记雷的位置,标记后无法取消(Y/N):\n");
			scanf("%c", &b);
			getchar();
			if ('Y' == b) {
				printf("请输入您确定的雷的坐标(一旦确认无法更改,输入0 0退出此 *** 作)\n");
				scanf("%d %d", &x1, &y1);
				if (0 != x1 && 0 != y1) {
					show[x1][y1] = 'z';
					DisplayBoard(show, ROW, COL);
				}
			}
		} while (x1 != 0 && y1 != 0 );
		printf("请输入要排雷的坐标:");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col) {
			if (show[x][y] != '*') {
				printf("该位置已经排查过了,请重新选择\n");
			}
			else {
				if (thunder[x][y] == '1') {
					printf("\a恭喜你!\n");
					printf("\a被炸死了!\n");
					DisplayBoard(thunder, ROW, COL);
					break;
				}
				else {
					win++;
					show[x][y] = get_thunder_count(thunder, x, y) + '0';
					//这里get_thunder_count函数里面将字符型转换为数字型
					//此处又将数字型转换为字符型,注意方法

					//展开功能
					if ('0' == show[x][y]) {   
						Spr_board(thunder, show, x, y);
					}
					DisplayBoard(show, ROW, COL);
				}
			}
		}
		else {
			printf("坐标输入不合法,请重新输入\n");
		}
	}
	if (win == EASYCOUNT) {
		printf("\a很遗憾!\n");
		printf("\a排雷成功!\n");
		DisplayBoard(show, ROW, COL);
	}
}
二、完整代码 1.game.h------游戏用到的函数
# include 
# include       
# include 
# define ROW 9     //棋盘行数,可自定义
# define COL 9     //棋盘列数,可自定义
# define ROWS (ROW + 2)
# define COLS (COL + 2)
//设置雷的个数
# define EASYCOUNT 1
//初始化
void Initboard(char board[ROWS][COLS], int rows, int cols, char ret);
//打印:
void DisplayBoard(char board[ROWS][COLS], int row, int col);
//布雷
void Getthunder(char board[ROWS][COLS], int row, int col);
//排雷
void FindBoard(char thunder[ROWS][COLS], char show[ROWS][COLS], int row, int col);
//找雷
int get_thunder_count(char thunder[ROWS][COLS], int rows, int cols);
//展开
void Spr_board(char thunder[ROWS][COLS], char show[ROWS][COLS], int x, int y);
2.test.c---------主逻辑

这里主要是代码的调用,也是一个主逻辑,代码的神经中枢

# define _CRT_SECURE_NO_WARNINGS
# include "game.h"
void menu() {
	printf("*****************\n");
	printf("**** 1. play ****\n");
	printf("**** 0. exit ****\n");
	printf("*****************\n");
}
void game() {
	srand((unsigned int)time(NULL));
	char thunder[ROWS][COLS] = { 0 };
	char show[ROWS][COLS] = { 0 };
	//初始化雷区和显示区
	Initboard(thunder, ROWS, COLS, '0');
	Initboard(show, ROWS, COLS, '*');
	//打印雷区和显示区:
	//DisplayBoard(thunder, ROW, COL);
	DisplayBoard(show, ROW, COL);
	//布雷
	Getthunder(thunder, ROW, COL);
	//DisplayBoard(thunder, ROW, COL);
	//排雷
	FindBoard(thunder, show, ROW, COL);
}
int main()
{
	int n = 0;
	do {
		menu();
		printf("请输入要完成的功能编号:");
		scanf("%d", &n);
		getchar();
		switch (n) {
		case 1:
			printf("玩游戏\n");
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("输入错误,请重新输入\n");
			break;
		}
	} while (n);
}
3. game.c---------游戏的实现

如果说test.c是一个领导,那么game.c就是里面的员工了,包含大部分的函数定义

# define _CRT_SECURE_NO_WARNINGS
# include "game.h"
//初始化
void Initboard(char board[ROWS][COLS], int rows, int cols, char ret) {
	int i = 0, j = 0;
	for (i = 0; i < rows; i++) {
		for (j = 0; j < cols; j++) {
			board[i][j] = ret;
		}
	}
}
//打印
void DisplayBoard(char board[ROWS][COLS], int row, int col) {
	int i = 0, j = 0;
	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 ", board[i][j]);
		}
		printf("\n");
	}
}
//布雷
void Getthunder(char board[ROWS][COLS], int row, int col) {
	int count = EASYCOUNT;
	while (count) {
		int i = rand() % 9 + 1;
		int j = rand() % 9 + 1;
		if (board[i][j] == '0') {
			board[i][j] = '1';
			count--;
		}
	}
}
//展开
void Spr_board(char thunder[ROWS][COLS], char show[ROWS][COLS], int x, int y) {
	
	if (x >= 1 && x <= 9 && y >= 1 && y <= 9) {
		int i = -1, j = -1;
		for (i = -1; i < 2; i++) {
			for (j = -1; j < 2; j++) {
				if (thunder[x + i][y + j] == '0') {
					if (show[x + i][y + j] == '*') {
						show[x + i][y + j] = get_thunder_count(thunder, x + i, y + j) + '0';
						if ('0' == show[x + i][y + j]) {
							show[x][y] = ' ';
							show[x +i][y + j] = ' ';
							//show[x][y] = ' ';
							//DisplayBoard(thunder, ROW, COL);
							//DisplayBoard(show, ROW, COL);
							Spr_board(thunder, show, x + i, y + j);
						}
					}
				}
			}
		}
	}
}
//找雷
int get_thunder_count(char thunder[ROWS][COLS], int x, int y) {
	return (thunder[x - 1][y - 1] + thunder[x - 1][y] + thunder[x - 1][y + 1] +
		thunder[x][y - 1] + thunder[x][y + 1] +
		thunder[x + 1][y - 1] + thunder[x + 1][y] + thunder[x + 1][y + 1] - 8 * '0');
}
//'1' - '0' = 1;
//'0' - '0' = 0;
//排雷
void FindBoard(char thunder[ROWS][COLS], char show[ROWS][COLS], int row, int col) {
	int x = 0, y = 0;
	int win = 0;
	char b = '0';
	while (win < ROW * COL - EASYCOUNT) {
		int x1 = 0, y1 = 0;
		do {
			printf("是否要标记雷的位置,标记后无法取消(Y/N):\n");
			scanf("%c", &b);
			getchar();
			if ('Y' == b) {
				printf("请输入您确定的雷的坐标(一旦确认无法更改,输入0 0退出此 *** 作)\n");
				scanf("%d %d", &x1, &y1);
				if (0 != x1 && 0 != y1) {
					show[x1][y1] = 'z';
					DisplayBoard(show, ROW, COL);
				}
			}
		} while (x1 != 0 && y1 != 0 );
		printf("请输入要排雷的坐标:");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col) {
			if (show[x][y] != '*') {
				printf("该位置已经排查过了,请重新选择\n");
			}
			else {
				if (thunder[x][y] == '1') {
					printf("\a恭喜你!\n");
					printf("\a被炸死了!\n");
					DisplayBoard(thunder, ROW, COL);
					break;
				}
				else {
					win++;
					show[x][y] = get_thunder_count(thunder, x, y) + '0';
					//这里get_thunder_count函数里面将字符型转换为数字型
					//此处又将数字型转换为字符型,注意方法

					//展开功能
					if ('0' == show[x][y]) {   
						Spr_board(thunder, show, x, y);
					}
					DisplayBoard(show, ROW, COL);
				}
			}
		}
		else {
			printf("坐标输入不合法,请重新输入\n");
		}
	}
	if (win == EASYCOUNT) {
		printf("\a很遗憾!\n");
		printf("\a排雷成功!\n");
		DisplayBoard(show, ROW, COL);
	}
}
总结

ok,大致就是这样了,如果发现哪里有bug还请大佬指出,小王在此谢过,有不清楚的地方也可以来问小王,很高兴和大家一起学习!!!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/874655.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-13
下一篇2022-05-13

发表评论

登录后才能评论

评论列表(0条)

    保存