C++程序开发——扫雷

C++程序开发——扫雷

//扫雷的类的定义

#pragma once

class Game{
public:
	//开始游戏
	void play();
	//退出游戏
	int quit();
	//游戏规则
	void rule();

private:
	//踩雷次数,作为失败条件
	int error = 0;
	//分数
	int score = 0;
	//最高分记录
	int Rocord[5] = { 0,0,0,0,0 };
	//地图
	int map[40][40];

	//地图的大小Size*Size
	int Size = 10;

	//容错
	int fault_tolerant = 10;

	//困难程度
	int _difficulty=1;

	//初始化
	void reset();

	//画地图
	void drawGrid();

	//查看格子的结果
	void Cheak();

	//判断是否游戏结束
	int isWin();

	//导入最高分记录
	void get_Rocord();

	//导出最高分记录
	void put_Rocord();

	//选择难度
	int  Selection_difficulty();

	//加载界面
	void loading();
};


然后是对类的函数的定义

//对Game类的成员函数的定义

#include "扫雷.h"
#include<Windows.h>
#include<iostream>
#include<fstream>
#include<time.h>
#include <conio.h>


#pragma warning(disable:4996) //这一行是为了能在 Visual Studio 2017内使用getch()函数

//定义最高分记录的存储地址
#define RocordPath "D:\\VS/扫雷最高分.txt"

using namespace std;

#define none   "█"


//定义5种情况,有雷和无雷,查看后的三种结果
enum players { Boom, None, Boom1, None1, Show1 };

//定义三种游戏难度
enum _Difficulty{Easy,General,Difficulty,Purgatory};

int D_size[4][2] = { {10,10} ,{15,8},{20,5},{30,3} };


//游戏规则的描述
void Game::rule() {
	loading();
	//清屏
	system("cls");
	cout << "\n\n\n\n";
	cout << "游戏规则:\n\n";
	cout << "1.当查看点为雷时,会显示“*”,并且将扣10分" << endl;
	cout << "2.当差看点不为雷且周围均无雷将显示周围所以格为“ ”(周围指的是相邻的8个格子)" << endl;
	cout << "3.当查看点不为雷,且周围存在雷时,将显示周围雷数" << endl;
	cout << "4.当踩到最大容错个数雷时游戏将失败" << endl;
	cout << "5.当不存在未查阅的非雷格时游戏胜利" << endl;
	cout << "\n\n\n\t\t\t\t30秒后自动退出该界面!";

	Sleep(30000);


}

//退出游戏
int  Game::quit() {


	system("cls");
	//定义控制台屏幕初始坐标
	COORD c = { 40, 13 };
	//设置控制台光标位置
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c);
	cout << "游戏结束!!!" << endl;

	Sleep(1000);

	loading();

	return 0;


}


//游戏模式
void Game::play() {
	//导入最高分记录
	get_Rocord();

	while (true) {
		//选择游戏难度
		_difficulty=Selection_difficulty();
		//默认游戏一直进行
		int res = 1;
		//初始化
		reset();
		//
		drawGrid();
		while (true) {

			//查看点
			Cheak();
			//
			drawGrid();


			if (!isWin()) {
				
				if (score > Rocord[_difficulty])Rocord[_difficulty] = score;
				put_Rocord();
				char s;
				cout << "是否再来一局?是(y|Y)/否(n|N)" << endl;
				cin >> s;
				if (s == 'y' || s == 'Y')res = 1;
				else res = 0;
				break;
			}
			
		}
		if (!res)break;
		
	}


}


//更新(初始化)
void Game::reset() {
	//数据初始化
	score = 0;
	error = 0;
	//棋盘初始化
	srand(time(NULL));
	for (int i = 0; i < Size; i++) {
		for (int j = 0; j < Size; j++) {
			int t = rand() % 2;
			if (t==1)map[j][i] = Boom;
			else map[j][i] = None;
			//cout << t<< " ";
		}
		//cout << endl;
	}
	
	
}


//画地图
void Game::drawGrid() {

	//清屏
	system("cls");
	//定义控制台屏幕初始坐标
	COORD c = { 0, 2 };
	//设置控制台光标位置
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c);
	//棋局初始状态
	for (int i = 0; i <= Size; i++) {
		if (i < 10)
			cout << i  << " ";
		else cout << i;
		for (int j = 0; j < Size; j++) {
			if (i == 0) {
				if (j < 9)
					cout << j + 1 << " ";
				else cout << j + 1;
			}
			else cout << none;
		}
		cout << endl;
	}

	for (int y = 0; y < Size; y++) {
		for (int x = 0; x < Size; x++) {
			if (map[x][y] == Boom1|| map[x][y] == None1) {
				//光标位置坐标
				COORD c = { x * 2 + 2, 3 + y };
				//设置控制台光标位置
				SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c);//GetStdHandle函数获得句柄
				string o;
				if (map[x][y] == Boom1) o = "* ";
				if (map[x][y] == None1) o = "  ";
				cout << o;
			}

			if (map[x][y] == Show1) {
				int cnt = 0;
				for (int i = x - 1; i <= x + 1; i++) {
					for (int j = y - 1; j <= y + 1; j++) {
						if (i >= 0 && i < Size && j >= 0 && j < Size) {
							if (map[i][j] == Boom || map[i][j] == Boom1)cnt++;
						}
					}
				}
				//光标位置坐标
				COORD c = { x*2+2, 3 + y };
				//设置控制台光标位置
				SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c);//GetStdHandle函数获得句柄
				cout << cnt << " ";

			}
		}
	}
	c.Y = Size+3;
	//设置控制台光标位置
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c);
	cout << "当前分数是:"<<score<<"\n最高纪录是:"<<Rocord[_difficulty]<<"\n请输入查看格的坐标" << endl;
	

}

//查看点结果
void Game::Cheak() {
	int x = 0, y = 0;

	cin >> x >> y;
	x -= 1, y -= 1;
	while(map[x][y] == Boom1 || map[x][y] == None1 || map[x][y] == Show1 || x < 0 || x >= Size || y < 0 || y >= Size) {
		//定义控制台屏幕初始坐标
		COORD c = { 0, 2 };
		c.Y = Size+6;
		//设置控制台光标位置
		SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c);
		cout << "该格以检查过或不在棋盘内,请重新输入" << endl;
		cin >> x >> y;
		x -= 1, y -= 1;
		
	}

	

	if (map[x][y] == Boom) {
		map[x][y] = Boom1;
		score -= 10;
		error++;
	}
	
	else {
		score += 10;
		int cnt = 0; 
		for (int i = x - 1; i <= x + 1; i++) {
			for (int j = y - 1; j <= y + 1; j++) {
				if (i >= 0 && i < Size && j >= 0 && j < Size) {
					if (map[i][j] == Boom || map[i][j] == Boom1)cnt++;
				}
			}
		}
		if (cnt == 0) {
			for (int i = x - 1; i <= x + 1; i++) {
				for (int j = y - 1; j <= y + 1; j++) {
					if (i >= 0 && i < Size && j >= 0 && j < Size) {
						map[i][j] = None1;
					}
				}
			}
		}
		else map[x][y] = Show1;
	}
	
}

//判断是否游戏结束
int Game::isWin() {
	int cnt = 0;
	for (int i = 0; i < Size; i++) {
		for (int j = 0; j < Size; j++) {
			if (map[i][j] == None)cnt++;
		}
	}

	if (cnt == 0) {
		system("cls");
		//定义控制台屏幕初始坐标
		COORD c = { 50, 15 };
		//设置控制台光标位置
		SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c);
		cout << "You Win!!!" << endl;
		return 0;
	}
	else if (error >= fault_tolerant) {
		system("cls");
		//定义控制台屏幕初始坐标
		COORD c = { 50, 15 };
		//设置控制台光标位置
		SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c);
		cout << "You Loss!!!" << endl;
		return 0;
	}
	else return 1;

}

//导入最高分记录
void Game::get_Rocord() {

	ifstream fin(RocordPath, ios::in);
	for (int i = 0; i < 5; i++) {
		fin >> Rocord[i];
	}
}

//导出最高分记录
void Game::put_Rocord() {

	ofstream fout(RocordPath, ios::out);
	for(int i=0;i<5;i++)
		fout << Rocord[i] << endl;
}

//选择难度
int  Game::Selection_difficulty() {
	//清屏
	system("cls");
	//定义控制台屏幕初始坐标
	COORD c = { 0, 6 };
	//设置控制台光标位置
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c);
	
	cout << "\t\t\t\t\t\t1.简单   (10*10格 10容错)\n\n" << endl;
	cout << "\t\t\t\t\t\t2.一般   (15*15格 8容错)\n\n" << endl;
	cout << "\t\t\t\t\t\t3.困难   (20*20格 5容错)\n\n" << endl;
	cout << "\t\t\t\t\t\t4.炼狱   (30*30格 3容错)\n\n" << endl;
	cout << "\t\t\t\t\t\t5.自定义\n\n" << endl; 
	cout << "\t\t\t\t\t\t请选择游戏难度:";
	int t = 1;
	cin >> t;
	while (t < 1 || t>5) {
		COORD c = { 0, 21 };
		//设置控制台光标位置
		SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c);
		cout << "\t\t\t\t\t\t输入错误请重新输入:" << endl;;
		cin >> t;
	}
	switch (t) {
	case 1:Size = D_size[Easy][0], fault_tolerant = D_size[Easy][1]; break;
	case 2:Size = D_size[General][0], fault_tolerant = D_size[General][1]; break;
	case 3:Size = D_size[Difficulty][0], fault_tolerant = D_size[Difficulty][1]; break;
	case 4:Size = D_size[Purgatory][0], fault_tolerant = D_size[Purgatory][1]; break;
	case 5: {
		//清屏
		system("cls");
		cout << "\n\n\n\n\n\t\t\t\t请输入地图尺码和最多踩雷失败数       (尺码在10-30,容错在10以内)";
			cout << "\t\t\t\t\t\t\t\t\t尺码:";
			cin >> Size;
			cout << "\n\t\t\t\t\t容错:";
			cin >> fault_tolerant;
	}break;
	}
	loading();
	return t;

}


void Game::loading() {

	COORD c = { 50,15 };
	//设置控制台光标位置
	int t = 6;
	while (t--) {
		system("cls");
		SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c);
		if(t%3==0)
			cout << "loading..." << endl;
		if (t % 3 == 1)
			cout << "loading.." << endl;
		if (t % 3 == 2)
			cout << "loading." << endl;
		Sleep(500);
	}


}

最后就是主函数部分

//扫雷游戏的主函数

#include<iostream>
#include<Windows.h>
#include"扫雷.h"
using namespace std;
int main() {
	Game game;
	while (true) {
		int t, g = 1;
		system("cls");
		//定义控制台屏幕初始坐标
		COORD c = { 30, 10 };
		//设置控制台光标位置
		SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c);
		cout << "欢迎来到 扫雷!!!\n\n\n\n\n\n";
		cout << "\t\t\t\t\t1.开始游戏\n\n\n\t\t\t\t\t2.阅读规则\n\n\n\t\t\t\t\t3.退出" << endl;
		cin >> t;
		switch (t) {
		case 1:game.play(); break;
		case 2:game.rule(); break;
		case 3:g=game.quit(); break;
		}
		if (g == 0)break;
	}
	return 0;
	
}

这是第一次写博客 也是第一次独立完成项目,有不足的地方,希望各位大牛牪犇指教

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值