C++简易版扫雷小游戏

游戏功能
扫雷。
游戏代码

#include<stdio.h>
#include<Windows.h>
#define YELLOW FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY
#define CYAN FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY
#define ORANGE FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY
#define PURPLE FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY
using namespace std;
int maxx = 9, maxy = 9, startx = 30, starty = 6, bombNum = 10;
class Cube {
    
    
private:
	bool ifHaveBomb;				//该方块是否含有地雷 
	bool ifOpen;					//该方块有无被玩家翻开
	int nearBombNumber;				//该区块周围8格的含有地雷的方块的数量
public: 
	void setOpen () {
    
    
    	//将Open的值改为true
		ifOpen = true;
	}
  	bool getOpen () {
    
    
    	//获取ifOpen的值
    	return ifOpen;
	}
  	void setNearBombNumber (int number) {
    
    
    	//给nearBombNumber赋值
    	nearBombNumber = number;
  	}
  	void haveBomb () {
    
    
    	//给方块放置地雷
    	ifHaveBomb = true;
  	}
  	bool getIfHaveBomb () {
    
    
    	//获取ifHaveBomb的值
    	return ifHaveBomb;
  	}
  	int getNearBombNumber () {
    
    
    	//获取nearBombNumber的值
    	return nearBombNumber;
  	}
  	void resetCube (bool ifhavebomb = false, bool ifopen = false, int nearbombnumber = 0) {
    
    
    	//初始化成员数据
    	ifHaveBomb = ifhavebomb;
    	ifOpen = ifopen;
    	nearBombNumber = nearbombnumber;
  	}
};
Cube cube[9][9];
void Goto (int x, int y);		//定位光标
void setBomb ();				//生成bombNum个炸弹并且放进随机的方块中
void show ();					//显示地雷阵
int checkAndSetNearBombNumber (int x, int y);//检查当前方块周围的雷数量 
void gameStart ();				//初始化游戏 
void showXY ();					//显示雷区坐标
bool player (bool &life);		//玩家输入坐标翻开方块
void message (bool life);		//玩家游戏结束后输出的信息
void autoOpen (int x, int y);	//玩家翻开的方块为不含雷且周围无雷的方块时,自动翻开周围无雷的方块
bool ifWin ();					//判断玩家是否扫雷成功
void showBomb ();				//游戏结束后显示地雷位置
int main () {
    
    
	gameStart ();
	show ();
	bool life = true, win = true;
	while (player (life) && !ifWin ());
	return 0;
	message (life && ifWin ());
	return 0;
}
void Goto (int x, int y) {
    
    
	COORD coord = {
    
    x, y};
	SetConsoleCursorPosition (GetStdHandle (STD_OUTPUT_HANDLE), coord);
}
void setBomb () {
    
    
	int bombNumber = bombNum;	
	srand ((unsigned) GetCurrentTime ());
	while (bombNumber--) {
    
    
    	int x = maxx + 1, y = maxy + 1;
    	while ((x >= maxx || y >= maxy) || cube[x][y].getIfHaveBomb ()) {
    
    
      		x = rand() % maxx;
      		y = rand() % maxy;
    	}
    	cube[x][y].haveBomb ();
  	}
}

void show () {
    
    
	system ("cls");
	showXY ();
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), CYAN);
	for (int i = 0; i < maxy; i++) {
    
    
		Goto (startx, starty + i);
    	for (int j = 0; j < maxx; j++) {
    
    
     		if (cube[j][i].getOpen()) {
    
    
        		if (!cube[j][i].getIfHaveBomb()) {
    
    
          			if (cube[j][i].getNearBombNumber() == 0) {
    
     //挖开无雷的方块显示该方块周围多少个方块含雷,若为0则显示空格
            			printf(" ");
          			} else {
    
    
            			printf(" %d", cube[j][i].getNearBombNumber ());
          			}
        		} else {
    
    
          			printf("×");//有雷的方块被挖开后显示×
        		}
      		} else {
    
    
        		printf("■");//未翻开的方块用■显示
      		}
    	}
  	}
}
void showXY() {
    
    
	SetConsoleTextAttribute (GetStdHandle (STD_OUTPUT_HANDLE), CYAN);
	Goto (startx - 3, starty + maxy / 2);
  	printf ("Y");
  	Goto(startx + maxx, starty - 2);
  	printf ("X");
  	SetConsoleTextAttribute (GetStdHandle (STD_OUTPUT_HANDLE), YELLOW);
  	for (int i = 0; i < maxy; i++) {
    
    
    	Goto(startx - 1, starty + i);
    	printf("%d ", i);
  	}
  	for (int i = 0; i < 2 * maxx; i += 2) {
    
    
    	Goto (startx + i + 1, starty - 1);
    	printf("%d ", i / 2);
  	}
}
int checkAndSetNearBombNumber (int x, int y) {
    
    
	int num = 0;
	if (cube[x][y].getIfHaveBomb()) {
    
    
		//若该方块有地雷,则不用判断它周围有几个雷
    	return 0;
  	} else {
    
    
    	//用两个循环当前方块周围8格扫一遍
    	for (int i = -1; i <= 1; i++) {
    
    
      		for (int j = -1; j <= 1; j++) {
    
    
        		int nextx = x + i, nexty = y + j;
        		if (!(nexty == y && nextx == x) && (nextx >= 0 && nextx <= maxx - 1) &&
          			(nexty >= 0 && nexty <= maxy - 1)) {
    
    
          			if (cube[nextx][nexty].getIfHaveBomb ()) {
    
    
           				num++;
          			}
        		}
      		}
    	}
		cube[x][y].setNearBombNumber (num);//设置该方块附近的地雷的数量
    	return 0;
	}
}
void gameStart () {
    
    
	for (int i = 0; i < maxy; i++) {
    
    
    	for (int j = 0; j < maxx; j++) {
    
    
      		cube[j][i].resetCube ();
    	}
  	}
	setBomb ();
	for (int i = 0; i < maxy; i++) {
    
    
    	for (int j = 0; j < maxx; j++) {
    
    
      		checkAndSetNearBombNumber (j, i);
    	}
  	}
}
bool player(bool &life) {
    
    
	int x, y;
	Goto (startx - 3, starty + maxy + 1);
  	printf("请输入坐标(x,y),x和y用空格隔开");
  	Goto (startx + maxx / 2, starty + maxy + 2);
  	scanf("%d%d", &x, &y);
  	if ((x < 0) || (x > maxx - 1) || (y < 0) || (y > maxy - 1)) {
    
    
    	//当玩家输入的坐标超出范围时
    	show ();
    	Goto (startx - 3, starty + maxy + 3);
    	printf ("该坐标不存在,请重新输入坐标");
    	Goto(startx + maxx / 2, starty + maxy + 2);
	} else if (cube[x][y].getIfHaveBomb()) {
    
    
    	//当玩家翻开的方块有地雷时
    	cube[x][y].setOpen ();
    	show ();
    	life = false;
   		return false;
  	} else if (!cube[x][y].getOpen ()) {
    
    
    	//当玩家翻开的方块无雷时
    	if (cube[x][y].getNearBombNumber() == 0) {
    
    
      		autoOpen (x, y);
      		cube[x][y].setOpen ();
      		show();
    	} else {
    
    
      		cube[x][y].setOpen();
      		show ();
    	}
	} else if (cube[x][y].getOpen()) {
    
    
    	//当玩家输入已翻开方块的坐标时
    	show ();
    	Goto (startx, starty + maxy + 3);
    	printf ("该方块已被挖开,请再次输入坐标");
    	Goto (startx + maxx / 2, starty + maxy + 2);
	}
  	ifWin ();
  	return true;
}
void message (bool result) {
    
    
	if (result) {
    
    
		//玩家胜利时输出的信息
    	showBomb ();
    	SetConsoleTextAttribute (GetStdHandle (STD_OUTPUT_HANDLE), YELLOW);
    	Goto (startx - 1, starty + maxy + 1);
    	printf("恭喜你,你胜利了!");
    	Goto (startx, starty + maxy + 2);
	} else {
    
    
    	//玩家失败时输出的信息
    	showBomb ();
    	SetConsoleTextAttribute (GetStdHandle (STD_OUTPUT_HANDLE), PURPLE);
    	Goto (startx - 1, starty + maxy + 1);
    	printf ("××你踩中地雷了××");
    	Goto (startx, starty + maxy + 2);
	}
}
void autoOpen (int x, int y) {
    
    
	for (int i = -1; i <= 1; i++) {
    
    
    	for (int j = -1; j <= 1; j++) {
    
    
      		int nextx = x + i, nexty = y + j;
      		if (!(nexty == y && nextx == x) && (nextx >= 0 && nextx <= maxx - 1) &&
        		(nexty >= 0 && nexty <= maxy - 1) && !cube[nextx][nexty].getOpen ()) {
    
    
        		if (cube[nextx][nexty].getNearBombNumber () == 0) {
    
    
          			cube[nextx][nexty].setOpen ();
          			autoOpen (nextx, nexty);
       			} else {
    
    
     				cube[nextx][nexty].setOpen ();
       			}
      		}
		}
	}
}
bool ifWin() {
    
    
	int num = 0;
	for (int i = 0; i < maxx; i++) {
    
    
    	for (int j = 0; j < maxy; j++) {
    
    
    		if (!cube[j][i].getOpen ()) {
    
    
        		num++;
      		}
    	}
  	}
  	return num == bombNum;
}
void showBomb () {
    
    
	for (int i = 0;i < maxy; i++) {
    
    
		for (int j = 0; j < maxx; j++) {
    
    
			if (cube[j][i].getIfHaveBomb ()) {
    
    
        		cube[j][i].setOpen ();
      		}
    	}
  	}
	show ();
}

猜你喜欢

转载自blog.csdn.net/yueyuedog/article/details/112517031