基于c++控制台的扫雷游戏

Screen   类用于与控制台交互

gotoxy(short x, short y)跳转到控制台的指定位置

void Init() 获取控制台 句柄

bool changeColor(WORD color)变更颜色

/*
0 = 黑色       8 = 灰色搜索
1 = 蓝色       9 = 淡蓝色
2 = 绿色       A = 淡绿色
3 = 浅绿色     B = 淡浅绿色
4 = 红色       C = 淡红色
5 = 紫色       D = 淡紫色
6 = 黄色       E = 淡黄色
7 = 白色       F = 亮白色

FOREGROUND_BLUE	字体颜色:蓝	1
FOREGROUND_GREEN	字体颜色:绿	2
FOREGROUND_RED	字体颜色:红	4
FOREGROUND_INTENSITY	前景色高亮显示	8
BACKGROUND_BLUE	背景颜色:蓝	16
BACKGROUND_GREEN	背景颜色:绿	32
BACKGROUND_RED	背景颜色:红	64
BACKGROUND_INTENSITY	背景色高亮显示	128
*/
class Screen {
public:
	void gotoxy(short x, short y) {
		COORD pos;
		pos.X = x;
		pos.Y = y;
		SetConsoleCursorPosition(hOut, pos);
	};
	void Init()
	{
		hOut = GetStdHandle(STD_OUTPUT_HANDLE);
		assert(hOut != 0);
	}
	bool changeColor(WORD color)
	{
		SetConsoleTextAttribute(hOut,color);
		return true;
	}
	static Screen* instance() {
		static Screen screen;
		return &screen;
	}
private:

	Screen() {
	}
	Screen(const Screen&);
	const Screen& operator=(const Screen&);
	HANDLE hOut;
	INPUT_RECORD inRec;/*  返回数据记录 */
	DWORD numRead; /*  返回已读取的记录数 */
};

  SL扫雷类

Init()初始化窗口高度宽度和类的数量,生成表格

InitTable() 有雷的地方值为-1,其它为周边雷的个数

DrawIn() 画窗口内部格子

DrawOut()画窗口边框

Run()运行游戏

bfs(int h,int w)对于值为0的格子,宽度搜索其周边的格子直到非0

show(int h,int w)当用户点击单击位置h,w 时被调用

完整代码:

#include<Windows.h>
#include<iostream>
#include<cassert>
using std::cout;
using std::cin;
#include<vector>
#include<time.h>
#include<conio.h>
#include<queue>
using std::pair;
using std::make_pair;
using std::queue;
using std::vector;

/*
0 = 黑色       8 = 灰色搜索
1 = 蓝色       9 = 淡蓝色
2 = 绿色       A = 淡绿色
3 = 浅绿色     B = 淡浅绿色
4 = 红色       C = 淡红色
5 = 紫色       D = 淡紫色
6 = 黄色       E = 淡黄色
7 = 白色       F = 亮白色

FOREGROUND_BLUE	字体颜色:蓝	1
FOREGROUND_GREEN	字体颜色:绿	2
FOREGROUND_RED	字体颜色:红	4
FOREGROUND_INTENSITY	前景色高亮显示	8
BACKGROUND_BLUE	背景颜色:蓝	16
BACKGROUND_GREEN	背景颜色:绿	32
BACKGROUND_RED	背景颜色:红	64
BACKGROUND_INTENSITY	背景色高亮显示	128
*/
class Screen {
public:
	void gotoxy(short x, short y) {
		COORD pos;
		pos.X = x;
		pos.Y = y;
		SetConsoleCursorPosition(hOut, pos);
	};
	void Init()
	{
		hOut = GetStdHandle(STD_OUTPUT_HANDLE);
		assert(hOut != 0);
	}
	bool changeColor(WORD color)
	{
		SetConsoleTextAttribute(hOut,color);
		return true;
	}
	static Screen* instance() {
		static Screen screen;
		return &screen;
	}
private:

	Screen() {
	}
	Screen(const Screen&);
	const Screen& operator=(const Screen&);
	HANDLE hOut;
	INPUT_RECORD inRec;/*  返回数据记录 */
	DWORD numRead; /*  返回已读取的记录数 */
};

class SL {
public:
	SL() {
		output = Screen::instance();
	};

	bool Init()
	{
		system("color 70");
		SetWidth();

		SetHeight();
		SetNum();
		InitTable();
		right = 0;
		return true;
	}

	void InitTable()
	{
		table.resize(Height);
		for (int h = 0; h < Height; h++)
		{
			table[h].resize(Width);
		}

		int n = num;
		for (int i = 0; i < Height; i++)
		{
			for (int j = 0; j < Width; j++)
			{
					n--;
					table[i][j] = -1;
					if (n <= 0) {
						j = Width;
						i = Height;
					}
			}
		}

		srand(time(0));
		for (int i = 0; i < Height; i++)
		{
			for (int j = 0; j < Width; j++)
			{
				int pi = rand() % Height;
				int pj = rand() % Width;
				std::swap(table[i][j], table[pi][pj]);
			}
		}

		for (int i = 0; i < Height; i++)
		{
			for (int j = 0; j < Width; j++)
			{
				if (table[i][j] == -1)
				{
					int pos[][2] = { {-1,-1},{-1,1},{-1,0},{0,1},{0,-1},{ 1,-1 },{ 1,1 },{ 1,0 } };

					for (int k = 0; k < 8; k++)
					{
						int hh = pos[k][0] + i;
						int ww = pos[k][1] + j;

						if (hh >= 0 && hh < Height && ww >= 0 && ww < Width && table[hh][ww] != -1)
						{
							table[hh][ww]++;
						}
					}

				}
			}
		}

		int a;
		a = 1;
	}

	void SetWidth()
	{
		output->gotoxy(0, 0);
		printf("%s", "请输入扫雷游戏的宽度:                              ");
		output->gotoxy(22, 0);

		cin >> Width;
		while (!check(Width, 20, 60)) {
			output->gotoxy(0, 0);
			printf("%s", "请重新输入扫雷游戏的宽度:                              ");
			output->gotoxy(26, 0);
			cin >> Width;
		}
	}

	void SetHeight()
	{
		output->gotoxy(0, 1);
		printf("%s", "请输入扫雷游戏的高度:                              ");
		output->gotoxy(22, 1);

		cin >> Height;
		while (!check(Height, 20, 60)) {
			output->gotoxy(0, 1);
			printf("%s", "请重新输入扫雷游戏的高度:                              ");
			output->gotoxy(26, 1);
			cin >> Height;
		}
	}

	void SetNum()
	{
		output->gotoxy(0, 2);
		printf("%s", "请输入雷的个数:                              ");
		output->gotoxy(22, 2);

		cin >> num;
		while ((num >= (Width*Height>>1))) {
			output->gotoxy(0, 2);
			printf("%s", "请重新输入雷的个数:                              ");
			output->gotoxy(26, 2);
			cin >> num;
		}
	}

	bool check(int val,int low,int height)
	{
		return val >= low && val <= height;
	}

	void DrawIn()
	{
		output->changeColor(0x76);
		for (int h = 0; h < Height; h++)
		{
			output->gotoxy(5, 4+h);
			for (int w = 0; w < Width; w++)
			{
				printf("%s", "■");
				/*
				if (table[h][w] == -1)
					printf("%s", "★");
				else
					printf("%c ", table[h][w]+‘0‘);
				*/

			}
		}
	}

	void DrawOut()
	{
		output->changeColor(0x75);
		output->gotoxy(3, 3);
		//printf("%s\n", "■");
		for (int w = 0; w < (Width+2);w++)
			printf("%s", "■");
		output->gotoxy(3, 3 + Height + 1);
		for (int w = 0; w < (Width + 2); w++)
			printf("%s", "■");
		for (int h = 0; h < (Height + 2); h++)
		{
			output->gotoxy(3, 3 + h);
			printf("%s", "■");
			output->gotoxy(3+(Width+1)*2, 3 + h);
			printf("%s", "■");
		}

	}

	void Run()
	{
		COORD pos;
		pos.X = 5;
		pos.Y = 4;
		output->gotoxy(5, 4);
		bool run = true;
		while (run)
		{
			char ch = _getch();
			switch (ch)
			{
			case 72:  //printf("UP\n"); break;
			{
				pos.Y--;
				pos.Y = pos.Y < 4 ? 4 : pos.Y;
				output->gotoxy(pos.X, pos.Y);
			}break;
			case 80:  //printf("DOWN\n"); break;
			{
				pos.Y++;
				pos.Y = pos.Y > (4 + Height - 1) ? (4 + Height - 1) : pos.Y;
				output->gotoxy(pos.X, pos.Y);
			}break;
			case 75:  //printf("LEFT\n"); break;
			{
				pos.X-=2;
				pos.X = pos.X >= 5 ? pos.X : 5;
				output->gotoxy(pos.X, pos.Y);
			}break;
			case 77:  //printf("RIGHT\n"); break;
			{
				pos.X += 2;
				pos.X = pos.X <= 5+(Width-1)*2 ? pos.X : 5 + (Width - 1) * 2;
				output->gotoxy(pos.X, pos.Y);
			}break;
			case 13:  //Enter
			{
				int h = pos.Y - 4;
				int w = (pos.X - 5) >> 1;
				bool ret = show(h, w);
				if (!ret)
				{
					output->gotoxy(70, 0);
					printf("你输了!!!");
					return;
				}
				else if((right+num) == (Width*Height))
				{
					output->gotoxy(70, 0);
					printf("胜利!!!");
					for (int h = 0; h < Height; h++)
					{
						for (int w = 0; w < Width; w++)
						{
							show(h, w);
						}
					}
					return;
				}
			}
			}
		}
	}

	bool show(int h,int w)
	{
		int ret = true;
		output->gotoxy(5 + w * 2, 4 + h);
		switch (table[h][w])
		{
		case -2:break;//已处理过
		case -1:
			printf("%s", "★");
			ret = false;
			break;
		case 0:
			bfs(h,w);
			break;
		default:
			printf("%c ", table[h][w]+‘0‘);
			right++;
			table[h][w] = -2;
		}
		output->gotoxy(5 + w * 2, 4 + h);
		return ret;
	}

	void bfs(int h,int w)
	{
		using std::queue;
		queue<pair<int,int>> q;
		q.push(make_pair(h, w));

		while (!q.empty())
		{
			pair<int, int> n = q.front();
			q.pop();
			int h = n.first;
			int w = n.second;
			if (table[h][w] == -2)continue;
			output->gotoxy(5 + w * 2, 4 + h);
			if (table[h][w] == 0)
			{
				printf("%s", "  ");
				right++;
				int pos[][2] = { { -1,-1 },{ -1,1 },{ -1,0 },{ 0,1 },{ 0,-1 },{ 1,-1 },{ 1,1 },{ 1,0 } };

				for (int k = 0; k < 8; k++)
				{
					int hh = pos[k][0] + h;
					int ww = pos[k][1] + w;
					if (InWindow(hh, ww) && table[hh][ww]>=0)
					{
						q.push(make_pair(hh, ww));
					}
				}
			}
			else
			{
				printf("%c ", table[h][w] + ‘0‘);
				right++;
			}
			table[h][w] = -2;

		}
	}

	bool InWindow(int h, int w)
	{
		return h >= 0 && h < Height && w >= 0 && w < Width;
	}

private:
	Screen* output;
	int Width;  //窗口宽度
	int Height; //窗口高度
	int num;    //雷的数量
	int right;
	vector<vector<int>> table;
};

int main()
{
	Screen::instance()->Init();
	Screen::instance()->gotoxy(20, 20);
	SL game;
	game.Init();
	game.DrawOut();
	game.DrawIn();
	game.Run();
	system("pause");
	return 0;
}

  

时间: 2024-10-05 23:26:44

基于c++控制台的扫雷游戏的相关文章

c++ 控制台版 扫雷游戏

白天看了一天书看累了,晚上瞅见扫雷游戏,就自己琢磨着做一个呗.想了一会,也没看别人怎么做的,大概1个多小时完成了这个简单版本的扫雷游戏,由于没怎么学过c#,界面的事情可能迟几天再做,明天要回家啦,哈哈! 先说思路,其实挺简单的. (1) 随机生成10个雷,标记到二维数组里,然后计算八个方向的雷的总数记录下来,这是预处理阶段. (2)输入要翻开的位置的坐标,如果是数字直接显示,是空白的话,这里采用bfs即宽度优先搜索解决,搜到最外层是数字(仅一层)时结束,具体详见代码. // 扫雷程序 #incl

基于C#—WPF的扫雷游戏

本人是大一学生,上半学期刚学完C语言.出于自己的兴趣同时也是哥哥的任务,在寒假这几天自学C#,利用WPF写了一个扫雷的小游戏. 自学教材:<C#入门经典(第六版)>,1月28日购入,1月29日到2月9日学习了前十六章,由于有C语言基础,在语法阶段学习起来比较轻松,不过在接触到面向对象的时候遇到了一些困难,对于一些概念的理解着实费了一些功夫,不过最后还是成功的理解了.整个程序的设计从2月10日开始,在2月12日程序基本完成.2月13日将已知的BUG都清除完毕. 扫雷很简单.一个程序的核心就是数据

C++实现简单的扫雷游戏(控制台版)

C++新手的代码,请各位多包涵. 用C++写的一个简单的控制台版扫雷游戏.玩家通过输入方块的坐标来翻开方块. 只是一个雏形,能够让玩家执行翻开方块的操作并且判断输赢,还未添加标记方块.游戏菜单.记录游戏时间.重新开一局等等的功能. 玩家输入坐标的方式来翻开方块只适用于小型的“雷区”,若“雷区”大了,用坐标会变得很不方便. 代码片段扫雷V1.1 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28

洛谷P2670 扫雷游戏

题目描述 扫雷游戏是一款十分经典的单机小游戏.在n行m列的雷区中有一些格子含有地雷(称之为地雷格),其他格子不含地雷(称之为非地雷格).玩家翻开一个非地雷格时,该格将会出现一个数字--提示周围格子中有多少个是地雷格.游戏的目标是在不翻出任何地雷格的条件下,找出所有的非地雷格. 现在给出n行m列的雷区中的地雷分布,要求计算出每个非地雷格周围的地雷格数. 注:一个格子的周围格子包括其上.下.左.右.左上.右上.左下.右下八个方向上与之直接相邻的格子. 输入输出格式 输入格式: 输入文件第一行是用一个

扫雷游戏

扫雷游戏 发布时间: 2017年8月15日 22:17   最后更新: 2017年8月15日 22:21   时间限制: 1000ms   内存限制: 128M 描述 扫雷游戏是一款十分经典的单机小游戏.在n行m列的雷区中有一些格子含有地雷(称之为地雷格),其他格子不含地雷(称之为非地雷格).玩家翻开一个非地雷格时,该格将会出现一个数字--提示周围格子中有多少个是地雷格.游戏的目标是在不翻出任何地雷格的条件下,找出所有的非地雷格. 现在给出n行m列的雷区中的地雷分布,要求计算出每个非地雷格周围的

很久木来博客园了,今天献上周末撸的扫雷游戏咯~~

下面先上效果图 上图为最终效果,界面没美化,有点丑将就将就,,,,哈哈 不多说,上代码看注释已经注释好多,扫雷主要难度在于计算但前点击周围你的安全区域,我的想法是:递归循环计算当前点击的上.下.左.右4个格子,如果遇到空白则继续,如果遇到周围有雷则停止. 由中心点往外扩散,在扩散中肯定回遇到已经处理过的格子,则跳过continue.... html代码 <!doctype html> <html> <head> <meta charset="UTF-8&

基于Cocos2dx开发卡牌游戏Demo_放开那三国 2.0

PS:下载地址在最下面 1.登录 2.副本选择 3.地图 4. 选择敌人 5. 战斗 6. 战斗结算 7. 地图拓展 8. 武将拓展 9. 下载地址 主程序(包含资源文件):点击打开链接 源代码:正在上传... 基于Cocos2dx开发卡牌游戏Demo_放开那三国 2.0,布布扣,bubuko.com

红包扫雷游戏软件开发

微信红包扫雷游戏开发,微信红包扫雷软件开发,联系微电188-2624-7572. 微信扫雷游戏模式介绍:1.选 择做庄家的粉丝,发红包可设置多少金额,多少红包数,多少红包尾数为雷, 2.发出去红包后其它粉丝可抢,如果抢的红包尾数是庄家设置的尾数那则是中雷,则需把庄家发的红包金额发给庄家.   以上是做庄家发红包,庄家不会亏本的,总会有一个中雷的,每做一次庄平台会送相对应的积分,积分可去换购产品,做庄家稳赚不亏 再说说如果你做为玩家抢红包,首先条件是你余额需有你抢庄家红包对等的钱,打个比方,庄家发

javascript模拟Windows系统下的扫雷游戏

javascript模拟Windows系统下的扫雷游戏. 说好的一周一篇随笔的,这才第三周就延迟交作业了,深深的自责中... 先玩一把 demo 很久以前写的 当时都没写注释的 刚加上了 (尼玛,好多自己都不认识了 ... ) 不足的敌方就是本来想写个游戏排名的统计的,等有空了再加上(好像每次都这么说 然后就等好久好久...) 还有就是没有实现:点击第一个格子不能是雷的功能 刚才在手机端 打开了下这篇文章 排版完全乱了... <style> ul{padding:0;list-style:no