游戏功能
扫雷。
游戏代码
#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 ();
}