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

C语言——扫雷游戏

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

C语言——扫雷游戏

        本篇文章主要为大家介绍C语言如何实现扫雷游戏,感兴趣的小伙伴们可以参考一下 

一、问题的描述

        雷区中随机布置一定数量的地雷,玩家需要尽快找出所有不是地雷的方块,但不许踩到地雷。玩家标记所有地雷后,选择排雷结束,然后游戏判断玩家是否完成扫雷。

 二、游戏设计的基本流程

1、创建游戏菜单。
2、创建和初始化雷区。
3、打印排雷雷区。
4、玩家选择相关操作,并输入坐标。

5、玩家选择排雷完成。

6、判断扫雷是否完成。

三、程序的具体实现 1. 菜单界面

用户选择 1 开始游戏, 选择 0 退出游戏。

void menu() {
	printf("*************************n");
	printf("******   1. play    *****n");
	printf("******   0. exit    *****n");
	printf("*************************nn");
}

void test() {
	int input = 0;
	srand((unsigned int)time(NULL));
	menu();

	do
	{
		printf("请输入你的选择:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			system("cls");
			game();
			menu();
			break;
		case 0:
			break;
		default:
			printf("您的输入有误,请重新输入");
			Sleep(200);
			system("cls");
			menu();
			break;
		}
	} while (input);
	system("cls");
	printf("欢迎下次使用!!!nn");
	Sleep(300);
}

int main() {
	test();

	return 0;
}
2. 创建雷区

要进行游戏,我们首先要创建一个雷区。
雷区:使用11行11列的二维数组来表示,元素类型是char。

使用宏定义:
1.推高代码可读性。
2.提高扩展性,便于修改雷区尺寸和地雷数量。

#ifndef __HEAD_H__
#define __HEAD_H__
#define _CRT_SECURE_NO_WARNINGS 1
#include 
#include 
#include 
#include 
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define EASY_COUNT 10

#endif
// 1. 布置好的雷的信息
	char mine[ROWS][COLS] = { 0 };
	// 2. 排查雷的信息
	char show[ROWS][COLS] = { 0 };
3. 初始化雷区

用 * 来初始化排雷区,隐藏雷区上面的地雷。

用 1 来初始化雷的位置,设置雷区的地雷。

void InitBoard(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;
		}
	}
}
4. 随机布雷

电脑随机设置地雷:

1.使用 随机数种子 srand((unsigned int)time(NULL))。
2.要在雷区空的地方布雷。

void SetMine(char board[ROWS][COLS], int row, int col) {
	int count = EASY_COUNT;
	while (count)
	{
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		if (board[x][y] == '0') {
			board[x][y] = '1';
			count--;
		}
	}
}
5. 打印雷区

用户在玩游戏的时候,要看到雷区。

void DisplayBoard(char board[ROWS][COLS], int row, int col) {
	for (int i = 0; i <= row; i++) {
		printf(" %d ",i);
		if(i < row)
			printf("|");
	}
	printf("n");
	for (int i = 0; i <= row; i++) {
		printf("---");
		if (i < row)
			printf("|");
	}
	printf("n");
	for (int i = 1; i <= row; i++) {
		printf(" %d |", i);
		for(int j = 1; j <= col; j++) {
			printf(" %c ", board[i][j]);
			if (j < col) {
				printf("|");
			}	
		}
		printf("n");
		if (i < row) {
			for (int j = 0; j <= row; j++) {
				printf("---");
				if (j < row)
					printf("|");
			}
			printf("n");
		}
	}
	printf("n");
}
6. 玩家排雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col) {
	int x = 0;
	int y = 0;
	int ck = 0;
	char ch = ' ';
	while (1) {
		DisplayBoard(show, ROW, COL);
		printf("-----------------------n");
		printf("-->    p. 排雷         n");
		printf("-->    b. 标记         n");
		printf("-->    e. 标记完成     n");
		printf("-----------------------nn");
		Flag:
		printf("请输入您的操作: ");
		getchar();
		scanf("%c", &ch);
		switch (ch)
		{
		case 'p': 
			{	P_1:
				printf("请输入坐标: ");
				scanf("%d", &x);
				scanf("%d", &y);
				if (x <= row && x >= 1 && y <= col && y >= 1) {
					if (mine[x][y] == '1') // 踩雷 
					{
						system("cls");
						printf("nT_T T_T T_T T_T T_T T_Tn");
						printf("很遗憾,你被炸死了!!!n");
						printf("T_T T_T T_T T_T T_T T_Tnn");
						DisplayBoard(mine, ROW, COL);
						printf("nn按任意键结束!nn");
						getchar();
						getchar();
						system("cls");
						goto End;
					}
					else // 不是雷
					{
						// 计算x,y 周围有几个雷?
						get_mine_count(mine, show, x, y);
						//DisplayBoard(show, ROW, COL);
						system("cls");
					}
				}
				else
				{
					printf("您输入坐标有误, 请重新输入^_^n");
					goto P_1;
				}
			}
			break;
		case 'b':
		{	B_1:
			printf("请输入坐标: ");
			scanf("%d", &x);
			scanf("%d", &y);
			if (x <= row && x >= 1 && y <= col && y >= 1) {
				MarkMine(mine, show, x, y);
				system("cls");
			}
			else
			{
				printf("您输入坐标有误, 请重新输入^_^n");
				goto B_1;
			}
		}
			break;
		case 'e':
			// 检查玩家的扫雷状态
			ck = judge(mine, show);
			if (ck == 1) {
				system("cls");
				printf("^_^^_^^_^^_^^_^^_^^_^^_^n");
				printf("恭喜你,扫雷完成!!!n");
				printf("^_^^_^^_^^_^^_^^_^^_^^_^n");
				printf("nn按任意键结束!nn");
				getchar();
				getchar();
				system("cls");
				goto End;
			}
			else
			{
				system("cls");
				printf("nT_T T_T T_T T_T T_T T_Tn");
				printf("很遗憾,扫雷失败!!!n");
				printf("T_T T_T T_T T_T T_T T_Tnnn");
				DisplayBoard(mine, ROW, COL);
				printf("nn按任意键结束!nn");
				getchar();
				getchar();
				system("cls");
				goto End;
			}
			break;
		default:
			printf("您输入操作有误, 请重新输入^_^n");
			goto Flag;
			break;
		}
	}
	End:
	;
}
7. 查看周围地雷数量
// 展开功能的实现,递归
int get_mine_count(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)
{	
	if (x <= ROW && x >= 1 && y <= COL && y >= 1)
	{
		if (show[x][y] == ' ')
		{
			return 0;
		}
		int n = mine[x - 1][y] +
			mine[x - 1][y - 1] +
			mine[x - 1][y + 1] +
			mine[x][y - 1] +
			mine[x][y + 1] +
			mine[x + 1][y] +
			mine[x + 1][y - 1] +
			mine[x + 1][y + 1] - 8 * '0';
		if (n == 0) {
			show[x][y] = ' ';
			get_mine_count(mine, show, x - 1, y);
			get_mine_count(mine, show, x-1, y-1);
			get_mine_count(mine, show, x-1, y+1);
			get_mine_count(mine, show, x, y-1);
			get_mine_count(mine, show, x, y+1);
			get_mine_count(mine, show, x+1, y);
			get_mine_count(mine, show, x+1, y-1);
			get_mine_count(mine, show, x+1, y+1);
		}
		else
		{
			show[x][y] = '0' + n;
			return 0;
		}
	}
	return 0;
}
8. 标记地雷
int MarkMine(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y) {
	if (show[x][y] == '$') {
		show[x][y] = '*';
	}
	else
	{
		show[x][y] = '$';
	}

	return 0;
}
9. 判断成败
int judge(char mine[ROWS][COLS], char show[ROWS][COLS]) {
	int count = 0;
	for (int i = 1; i <= ROW; i++) {
		for (int j = 1; j <= COL; j++) {
			if (show[i][j] == '$') {
				if (mine[i][j] == '1') {
					count++;
				}
			}
		}
	}
	if (count == EASY_COUNT) {
		return 1;
	}
	return 0;
}
四、完整代码 1. head.h
#ifndef __HEAD_H__
#define __HEAD_H__
#define _CRT_SECURE_NO_WARNINGS 1
#include 
#include 
#include 
#include 
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define EASY_COUNT 10

void game();
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 FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
int get_mine_count(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y);
int MarkMine(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y);
int judge(char mine[ROWS][COLS], char show[ROWS][COLS]);

#endif // !__HEAD_H__
2. game.c
#include"head.h"

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);
	// 布置雷
	SetMine(mine, ROW, COL);
	//DisplayBoard(mine, ROW, COL);
	// 扫雷
	FindMine(mine,show,ROW,COL);
}

void InitBoard(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 DisplayBoard(char board[ROWS][COLS], int row, int col) {
	for (int i = 0; i <= row; i++) {
		printf(" %d ",i);
		if(i < row)
			printf("|");
	}
	printf("n");
	for (int i = 0; i <= row; i++) {
		printf("---");
		if (i < row)
			printf("|");
	}
	printf("n");
	for (int i = 1; i <= row; i++) {
		printf(" %d |", i);
		for(int j = 1; j <= col; j++) {
			printf(" %c ", board[i][j]);
			if (j < col) {
				printf("|");
			}	
		}
		printf("n");
		if (i < row) {
			for (int j = 0; j <= row; j++) {
				printf("---");
				if (j < row)
					printf("|");
			}
			printf("n");
		}
	}
	printf("n");
}

void SetMine(char board[ROWS][COLS], int row, int col) {
	int count = EASY_COUNT;
	while (count)
	{
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		if (board[x][y] == '0') {
			board[x][y] = '1';
			count--;
		}
	}
}

void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col) {
	int x = 0;
	int y = 0;
	int ck = 0;
	char ch = ' ';
	while (1) {
		DisplayBoard(show, ROW, COL);
		printf("-----------------------n");
		printf("-->    p. 排雷         n");
		printf("-->    b. 标记         n");
		printf("-->    e. 标记完成     n");
		printf("-----------------------nn");
		Flag:
		printf("请输入您的操作: ");
		getchar();
		scanf("%c", &ch);
		switch (ch)
		{
		case 'p': 
			{	P_1:
				printf("请输入坐标: ");
				scanf("%d", &x);
				scanf("%d", &y);
				if (x <= row && x >= 1 && y <= col && y >= 1) {
					if (mine[x][y] == '1') // 踩雷 
					{
						system("cls");
						printf("nT_T T_T T_T T_T T_T T_Tn");
						printf("很遗憾,你被炸死了!!!n");
						printf("T_T T_T T_T T_T T_T T_Tnn");
						DisplayBoard(mine, ROW, COL);
						printf("nn按任意键结束!nn");
						getchar();
						getchar();
						system("cls");
						goto End;
					}
					else // 不是雷
					{
						// 计算x,y 周围有几个雷?
						get_mine_count(mine, show, x, y);
						//DisplayBoard(show, ROW, COL);
						system("cls");
					}
				}
				else
				{
					printf("您输入坐标有误, 请重新输入^_^n");
					goto P_1;
				}
			}
			break;
		case 'b':
		{	B_1:
			printf("请输入坐标: ");
			scanf("%d", &x);
			scanf("%d", &y);
			if (x <= row && x >= 1 && y <= col && y >= 1) {
				MarkMine(mine, show, x, y);
				system("cls");
			}
			else
			{
				printf("您输入坐标有误, 请重新输入^_^n");
				goto B_1;
			}
		}
			break;
		case 'e':
			// 检查玩家的扫雷状态
			ck = judge(mine, show);
			if (ck == 1) {
				system("cls");
				printf("^_^^_^^_^^_^^_^^_^^_^^_^n");
				printf("恭喜你,扫雷完成!!!n");
				printf("^_^^_^^_^^_^^_^^_^^_^^_^n");
				printf("nn按任意键结束!nn");
				getchar();
				getchar();
				system("cls");
				goto End;
			}
			else
			{
				system("cls");
				printf("nT_T T_T T_T T_T T_T T_Tn");
				printf("很遗憾,扫雷失败!!!n");
				printf("T_T T_T T_T T_T T_T T_Tnnn");
				DisplayBoard(mine, ROW, COL);
				printf("nn按任意键结束!nn");
				getchar();
				getchar();
				system("cls");
				goto End;
			}
			break;
		default:
			printf("您输入操作有误, 请重新输入^_^n");
			goto Flag;
			break;
		}
	}
	End:
	;
}

// 展开功能的实现,递归
int get_mine_count(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)
{	
	if (x <= ROW && x >= 1 && y <= COL && y >= 1)
	{
		if (show[x][y] == ' ')
		{
			return 0;
		}
		int n = mine[x - 1][y] +
			mine[x - 1][y - 1] +
			mine[x - 1][y + 1] +
			mine[x][y - 1] +
			mine[x][y + 1] +
			mine[x + 1][y] +
			mine[x + 1][y - 1] +
			mine[x + 1][y + 1] - 8 * '0';
		if (n == 0) {
			show[x][y] = ' ';
			get_mine_count(mine, show, x - 1, y);
			get_mine_count(mine, show, x-1, y-1);
			get_mine_count(mine, show, x-1, y+1);
			get_mine_count(mine, show, x, y-1);
			get_mine_count(mine, show, x, y+1);
			get_mine_count(mine, show, x+1, y);
			get_mine_count(mine, show, x+1, y-1);
			get_mine_count(mine, show, x+1, y+1);
		}
		else
		{
			show[x][y] = '0' + n;
			return 0;
		}
	}
	return 0;
}

int MarkMine(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y) {
	if (show[x][y] == '$') {
		show[x][y] = '*';
	}
	else
	{
		show[x][y] = '$';
	}

	return 0;
}

int judge(char mine[ROWS][COLS], char show[ROWS][COLS]) {
	int count = 0;
	for (int i = 1; i <= ROW; i++) {
		for (int j = 1; j <= COL; j++) {
			if (show[i][j] == '$') {
				if (mine[i][j] == '1') {
					count++;
				}
			}
		}
	}
	if (count == EASY_COUNT) {
		return 1;
	}
	return 0;
}
3. main.c
#include "head.h"

void menu() {
	printf("*************************n");
	printf("******   1. play    *****n");
	printf("******   0. exit    *****n");
	printf("*************************nn");
}

void test() {
	int input = 0;
	srand((unsigned int)time(NULL));
	menu();

	do
	{
		printf("请输入你的选择:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			system("cls");
			game();
			menu();
			break;
		case 0:
			break;
		default:
			printf("您的输入有误,请重新输入");
			Sleep(200);
			system("cls");
			menu();
			break;
		}
	} while (input);
	system("cls");
	printf("欢迎下次使用!!!nn");
	Sleep(300);
}

int main() {
	test();

	return 0;
}
五、游戏演示 1. 菜单界面

2. 游戏界面

3. 完成界面

 

 

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

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

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