IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 简易扫雷游戏 -> 正文阅读

[C++知识库]简易扫雷游戏

相信大家都玩过扫雷游戏,在学习了二维数组之后,我也用c语言写了一个简单的扫雷游戏规则如下:

1.通过对宏Row和宏List来设置游戏的棋盘大小(如果想玩10x10的扫雷则需设置Row和List为12);

2.通过对 宏BoomNumber 来设置局中雷的个数(雷的个数需要<=(Row-2)*(List-2));

3.对 用户输入要扫描的坐标,如果有雷则雷爆炸游戏结束,如果没有雷则统计出该坐标周围的雷的个数,一直循环此操作,直到棋盘中未扫描的地方全是雷为止则扫雷成功。

#pragma warning (disable:4996)
#pragma once
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#define Row 12
#define List 12
#define BoomNumber 20
#define Boom '1'//1为有雷
#define nice '0'
extern void Game();
extern void SetMine(char MineBoard, int row, int list);
extern void Select(char MineBoard, int row, int list);
extern void Menu();
extern void CountBoom(char MineBoard[][List], int row, int list, int x, int y);

这便是扫雷游戏的头文件,里面声明的函数和定义的宏会在下文中一一解释

问题的关键在于:

1.如何给棋盘随机埋入BoomNumber个雷

2.用户选择扫雷的坐标后系统发现此处没有雷如何统计出周围雷的个数并且让用户看到

考虑到只有在雷爆炸后用户才需要知道系统埋雷的位置,其余时间不需要让用户看见埋雷的位置,为了方便我们需要设置两个棋盘,一个用来埋雷另外一个则展示给用户,棋盘有横有纵,所以我们考虑用 两个类型相同的二维数组埋雷的棋盘为MineBoard[Row][List]展示给用户的则为ShowBoard[Row][List],考虑到内存的问题我们设置这两个数组都为char类型;

棋盘的问题解决了,那么在用户第一次选择坐标之前我们还需要1.埋雷;2.把ShowBoard数组展示出来,因为需要随机埋下BoomNumber个雷所以我们使用随机数的方法,让系统随机产生坐标而且不能有重复的坐标,在生成的坐标位置埋入Boom,其余位置则为nice(没有雷),因为埋雷是少数操作我们先初始化MineBoard数组里的元素全为nice;

void SetMine(char MineBoard[][List], int row, int list)
{
	for (int i = 0;i < row;i++)
	{
		for (int j = 0;j < list;j++)
		{
			MineBoard[i][j] =nice;
		}
	}//无雷为nice
	int num = 0;
	int _x;
	int _y;
	while (num < BoomNumber)
	{
		_x = 1 + rand()%(Row-2);
		_y = 1 + rand()%(Row-2);
		if (MineBoard[_x][_y] != Boom)
		{
			MineBoard[_x][_y] = Boom;
			num++;
		}
	}
}

埋雷完成后则给用户展示ShowBoard

void ShowBoards(char ShowBoard[][List], int row, int list)
{
	printf("  ");
	for (int x = 1;x < list - 1;x++)
	{
		printf(" %2d ",x);
	}
	printf("\n");
	for (int i = 1;i < row-1;i++)
	{
		printf(" %2d",i);
		for (int j = 1;j < list-1;j++)
		{
			printf(" %c |",ShowBoard[i][j]);
		}
		printf("\n");
		printf("   ");
		for (int k = 0;k < row - 2;k++)
		{
			printf("----");
		}
		printf("\n");
	}
}

此时用户选择要扫描的坐标若该坐标没有雷则统计其周围雷的个数,要是有雷则中雷游戏结束

考虑到用户输入的坐标可能已经被扫描或者用户输入的坐标不在(1.1)~(Row-2,Row-2)这个范围内我们就要提醒用户输入的坐标以及被扫描或者输入的坐标不合法,直到用户为扫描的坐标全为Boom为止

void Select(char ShowBoard[Row][List], char MineBoard[][List], int row, int list)
{
	int step = 0;
	int x = 0;
	int y = 0;
	while (step < ((row - 2) * (list - 2) - BoomNumber))
	{
		printf("请输入你要排雷的坐标:(x,y)\n");
		scanf("%d,%d", &x, &y);
		if (x > 0 && x < (List-1) && y>0 && y < (List-1))
		{
			if (ShowBoard[x][y] == 42)
			{
				if (MineBoard[x][y] == nice)
				{
					CountBoom(ShowBoard, MineBoard, Row, List,x,y);
					system("cls");
					ShowBoards(ShowBoard, Row, List);
					step++;
					if (step == ((row - 2) * (list - 2) - BoomNumber))
					{
						printf("扫雷成功!\n");
						Menu();
					}
				}
				else if(MineBoard[x][y] == Boom)
				{
					system("cls");
					printf("你已经被炸死了!游戏结束\n");
					ShowMineBoard(MineBoard, Row, List);
				}
			}
			else {
				printf("此处已经被扫描,请输入合法的坐标\n");
			}
		}
		else {
			printf("请输入合法的坐标\n");
		}
	}
}

统计用户选择的坐标的周围雷的个数并让这个数字展示在ShowBoard上,我用到了sprintf函数来把数字转换成字符(因为我们定义ShowBoard数组为char类型)统计雷的个数时因为MineBoard数组也是char类型在把(x,y)周围8个位置的雷的个数加起来时用到的是Boom的ascii码值,又因为有雷为‘1’(ascii码值为49)没有雷为‘0’(ascii码值为48)所以在运算后需要减去8个‘0’的ASCII码值,再返回去看定义这两个棋盘时我们只需要10x10的棋盘却定义了12x12的棋盘这是为了方便统计边缘棋盘周围雷的个数

void CountBoom(char ShowBoard[Row][List],char MineBoard[][List], int row, int list, int x, int y)
{
	int a = MineBoard[x][y + 1]\
		+ MineBoard[x + 1][y + 1] + MineBoard[x - 1][y + 1] \
		+ MineBoard[x][y - 1] + MineBoard[x + 1][y - 1] \
		+ MineBoard[x - 1][y - 1] + MineBoard[x - 1][y] \
		+ MineBoard[x + 1][y] - 384;
	char  arr[32];//设置一个较大的数组防止溢出
   sprintf(arr, "%d", a);//把数字转成字符
	ShowBoard[x][y] = arr[0];
}

至此扫雷游戏的主要逻辑已经梳理完毕

#include"FindMine.h"
void Menu()
{
	printf("*****1.开始游戏*****\n");
	printf("*****2.退出游戏*****\n");
	printf("请选择:\n");
	int a = 0;
	scanf("%d", &a);
	system("cls");
	if (a == 1)
	{
		Game();
	}
	else if (a == 2)
	{
		exit(0);
	}
	else {
		printf("输入有误,请重新选择\n");
		Menu();
	}
}
void Game()
{
	char ShowBoard[Row][List];
	for (int i = 0;i < Row;i++)
	{
		for (int j = 0;j < List;j++)
		{
			ShowBoard[i][j] = '*';
		}
	}
	char MineBoard[Row][List];
	SetMine(MineBoard, Row, List);
	ShowBoards(ShowBoard, Row, List);
	Select(ShowBoard, MineBoard, Row, List);
}
int main()
{
	srand((unsigned int)time(NULL));
	Menu();
	return 0;
}

这些为用户可见的函数

#include"FindMine.h"
void ShowBoards(char ShowBoard[][List], int row, int list)
{
	printf("  ");
	for (int x = 1;x < list - 1;x++)
	{
		printf(" %2d ",x);
	}
	printf("\n");
	for (int i = 1;i < row-1;i++)
	{
		printf(" %2d",i);
		for (int j = 1;j < list-1;j++)
		{
			printf(" %c |",ShowBoard[i][j]);
		}
		printf("\n");
		printf("   ");
		for (int k = 0;k < row - 2;k++)
		{
			printf("----");
		}
		printf("\n");
	}
}
void ShowMineBoard(char MineBoard[][List], int row, int list)
{
	for (int i = 1;i < row-1;i++)
	{
		for (int j = 1;j < list-1;j++)
		{
			printf("%c", MineBoard[i][j]);
		}
		printf("\n");
	}
	Menu();
}
void CountBoom(char ShowBoard[Row][List],char MineBoard[][List], int row, int list, int x, int y)
{
	int a = MineBoard[x][y + 1]\
		+ MineBoard[x + 1][y + 1] + MineBoard[x - 1][y + 1] \
		+ MineBoard[x][y - 1] + MineBoard[x + 1][y - 1] \
		+ MineBoard[x - 1][y - 1] + MineBoard[x - 1][y] \
		+ MineBoard[x + 1][y] - 384;
	char  arr[32];//设置一个较大的数组防止溢出
   sprintf(arr, "%d", a);//把数字转成字符
	ShowBoard[x][y] = arr[0];
}
void Select(char ShowBoard[Row][List], char MineBoard[][List], int row, int list)
{
	int step = 0;
	int x = 0;
	int y = 0;
	while (step < ((row - 2) * (list - 2) - BoomNumber))
	{
		printf("请输入你要排雷的坐标:(x,y)\n");
		scanf("%d,%d", &x, &y);
		if (x > 0 && x < (List-1) && y>0 && y < (List-1))
		{
			if (ShowBoard[x][y] == 42)
			{
				if (MineBoard[x][y] == nice)
				{
					CountBoom(ShowBoard, MineBoard, Row, List,x,y);
					system("cls");
					ShowBoards(ShowBoard, Row, List);
					step++;
					if (step == ((row - 2) * (list - 2) - BoomNumber))
					{
						printf("扫雷成功!\n");
						Menu();
					}
				}
				else if(MineBoard[x][y] == Boom)
				{
					system("cls");
					printf("你已经被炸死了!游戏结束\n");
					ShowMineBoard(MineBoard, Row, List);
				}
			}
			else {
				printf("此处已经被扫描,请输入合法的坐标\n");
			}
		}
		else {
			printf("请输入合法的坐标\n");
		}
	}
}
void SetMine(char MineBoard[][List], int row, int list)
{
	for (int i = 0;i < row;i++)
	{
		for (int j = 0;j < list;j++)
		{
			MineBoard[i][j] =nice;
		}
	}//无雷为nice
	int num = 0;
	int _x;
	int _y;
	while (num < BoomNumber)
	{
		_x = 1 + rand()%(Row-2);
		_y = 1 + rand()%(Row-2);
		if (MineBoard[_x][_y] != Boom)
		{
			MineBoard[_x][_y] = Boom;
			num++;
		}
	}
}

以上则为Game函数中需要调用的函数

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-11-28 11:05:10  更:2021-11-28 11:06:44 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 9:22:44-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码