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++知识库]C++简单扫雷

?简单扫雷

简易控制台版,实现了基本功能。

?

?用>标记现在所处的格,显示剩余雷数(每标记一个减1)。

操作方式:

使用键盘操作,wasd移动,q标记,e翻开

?需求:

1、e翻开,如果是数字显示,0即周围无雷继续翻开周围格,直到无可翻的;
2、如果是雷结束游戏,显示全部雷位置;
3、e已经翻开的且周围8格标记雷数=该格数字,自动翻开其余格,有雷结束游戏;
4、当所有非雷位置全部翻开游戏结束,胜利;
5、生成时保证第一次点击不是雷。

默认是16 * 16大小,共16 * 16 / 9 = 28个雷,可以更改源码中宏定义来改变大小。

一、头文件及变量、函数声名

bomb,炸弹数,默认是总格数的1/9
b,剩余雷数
str,存显示用字符
start,判定是否开始
temp,存放已经翻开的格数,用来判定胜利
map,用来存雷和数字
map2,用来存状态(未翻开、翻开、标记)
m,遍历用的数组
pointer,指针,利用一个数字表示二维坐标,pointer = x + width * y;
????????x = pointer / width; y = pointer % width; 一对一唯一确定

#include<iostream>
#include<conio.h>
#include<time.h>
#include<stdlib.h>
using namespace std;
#define height	16		//x	行
#define width	16		//y	列

//************************  变  量  *******************************
int bomb = width * height /9;			//雷数		1/9的格数 
int b = bomb;			//剩余雷数
string str = " 12345678*";	//显示
bool start = false;		//是否开始
int temp = 0;			//结束标志

int map[height][width] = { 0 };			//数字地图,9雷
int map2[height][width] = { 0 };		//状态地图,0未翻开,1翻开,2标记
int m[8][2] = { -1,-1,0,-1,1,-1,-1,0,1,0,-1,1,0,1,1,1 }; //8向遍历
int pointer = width / 2 + height * width / 2;	//指针pointer = x + width * y
                                        //x = pointer / width; y = pointer % width;

//********************  主  要  函  数  ******************************
bool over(int x, int y);	// 判断越界 
void display();				// 显示 
void operate(int input);	// 操作 
void sign();				// 标记 
void click(int x, int y);	// 扫雷 
void setMine();				// 生成雷 
void count(int x, int y);	// 计算地图 
bool isEnd();				// 是否结束 
void win();					// 胜利 
void lost();				// 失败 

二、函数定义

?1.判断越界,越界返回真,否则返回假

//判断越界
bool over(int x, int y)
{
	if (x < 0 || y < 0 || x > height - 1 || y > width - 1)
	{
		return true;
	}
	else
	{
		return false;
	}
}

2.显示界面,根据两个地图打印

//显示
void display()
{
	system("cls");
	for (int i = 0; i < height; i++)
	{
		for (int j = 0; j < width; j++)
		{
			//map[i][j] = 9;
			if (pointer / width == i && pointer % width == j)
			{
				cout << '>';
			}
			else
			{
				cout << " ";
			}
			if (map2[i][j] == 1)
			{
				cout << str[map[i][j]];
			}
			else if (map2[i][j] == 2)
			{
				cout << "!";
			}
			else
			{
				cout << "@";
			}
		}
		cout << endl;
	}
}

3.操作

//操作
void operate(int input)
{
	if (input == 'a' && pointer % width > 0)
	{
		pointer -= 1;
	}
	if (input == 'd' && pointer % width < width - 1)
	{
		pointer += 1;
	}
	if (input == 'w' && pointer / width > 0)
	{
		pointer -= width;
	}
	if (input == 's' && pointer / width < height - 1)
	{
		pointer += width;
	}
	if (input == 'e')
	{
		if (!start) setMine();
		click(pointer / width, pointer % width);
	}
	if (input == 'q')
	{
		if (!start) setMine();
		sign();
	}
}

4.标记功能

//标记
void sign()
{
	if (map2[pointer / width][pointer % width] == 0)
	{
		map2[pointer / width][pointer % width] = 2;
		b--;
		return;
	}
	if (map2[pointer / width][pointer % width] == 2)
	{
		map2[pointer / width][pointer % width] = 0;
		b++;
		return;
	}
}

5.翻开(点击)功能,用了点递归,很容易把自己绕死导致重复扫,最后爆内存

//扫雷 
void click(int x, int y)
{
	//如果点击的是未翻开的
	if (map2[x][y] == 0)
	{
		map2[x][y] = 1;
		temp += 1;
		if (map[x][y] == 9)
		{
			temp = -1;
			return;
		}
		if (map[x][y] == 0)
		{
			for (int i = 0; i < 8; i++)
			{
				if (!over(x + m[i][0], y + m[i][1]))
				{
					click(x + m[i][0], y + m[i][1]);
				}
			}
		}
	}
	//如果点击的是翻开的且不是0--减少运算
	else if (map2[x][y] == 1 && map[x][y] != 0)
	{
		int t = 0;
		for (int i = 0; i < 8; i++)
		{
			if (!over(x + m[i][0], y + m[i][1]))
			{
				if (map2[x + m[i][0]][y + m[i][1]] == 2)
				{
					t += 1;
				}
			}
		}
		//周围标记数=格子数字
		if (t == map[x][y])
		{
			for (int i = 0; i < 8; i++)
			{
				if (!over(x + m[i][0], y + m[i][1]))
				{
					//将未翻开的翻开
					if (map2[x + m[i][0]][y + m[i][1]] == 0)
					{
						//是0继续翻周围
						if (map[x + m[i][0]][y + m[i][1]] == 0)
							click(x + m[i][0], y + m[i][1]);
						else
						{
							map2[x + m[i][0]][y + m[i][1]] = 1;
							temp += 1;
							if (map[x + m[i][0]][y + m[i][1]] == 9)
							{
								temp = -1;
								return;
							}
						}
					}
				}
			}
		}
	}
}

6.生成雷,第一次不会踩雷

//生成雷
void setMine()
{
	srand((unsigned)time(NULL));
	int m = 0;
	while (m != bomb)
	{
		int r = rand() % (width * height);
		int r1 = r / width;
		int r2 = r % width;
		if (r1 == pointer / width && r2 == pointer % width) continue;
		if (map[r1][r2] != 9)
		{
			m += 1;
			map[r1][r2] = 9;
			count(r1, r2);
		}
		//cout << r << "," << r1 << "," << r2 << endl;
	}
	start = true;
}

7.计算数字,生成雷后立即计算

//计算数字
void count(int x, int y)
{
	for (int i = 0; i < 8; i++)
	{
		if (!over(x + m[i][0], y + m[i][1]))
		{
			if (map[x + m[i][0]][y + m[i][1]] != 9)
			{
				map[x + m[i][0]][y + m[i][1]] += 1;
			}
		}
	}
}

8.判断是否结束游戏,跳转失败或跳转胜利

//判断是否结束 
bool isEnd()
{
	if (temp == -1)
	{
		lost();
		return true;
	}
	else if (width * height - temp == bomb)
	{
		win();
		return true;
	}
	else
	{
		return false;
	}
}

//胜利 
void win()
{
	for (int i = 0; i < height; i++)
	{
		for (int j = 0; j < width; j++)
		{
			map2[i][j] = 1;
		}
	}
	display();
	cout << "you win!" << endl;
}

//失败 
void lost()
{
	for (int i = 0; i < height; i++)
	{
		for (int j = 0; j < width; j++)
		{
			if (map[i][j] == 9)
				map2[i][j] = 1;
		}
	}
	display();
	cout << "you lost!" << endl;
}

三、主函数

?

//主函数 
int main()
{
	display();
	cout << "mine: " << bomb << endl;
	while (true)
	{
		int input = _getch();
		operate(input);
		if (isEnd())
		{
			break;
		}
		display();
		cout << "mine: " << b << endl;
	}
	system("pause"); 
	return 0;
}

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-10-01 16:38:20  更:2021-10-01 16:38:39 
 
开发: 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/23 23:42:37-

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