本文实例为大家分享了C++实现简单扫雷小游戏的具体代码,供大家参考,具体内容如下
头文件Mine_Sweep.h
- #include <iostream>
- #include <ctime>
- #include <cstdlib>
- #include <algorithm>
- #include <queue>
- #include <Windows.h>
- using namespace std;
- typedef pair<int, int> P;
- const int M = 10;
- const int N = 10;
- void InitGame(int A[M][N]);//初始化游戏
- void Map(int A[M][N], int Static[M][N]);//地图
- void Result(int A[M][N]);//游戏结果
- int IfSafety(int A[M][N],int x,int y);//周围是否有地雷
- void Operate(int A[M][N],int Static[M][N], int x, int y); //操作产生的影响
- void Welcome(); //欢迎界面
- void GameOver(); //结束界面
- void gotoxy(int x, int y); //指针位置
- void color(int c); //改变颜色
实现部分
- #include"Mine_Sweep.h"
- void InitGame(int A[M][N])
- {
- //从右开始顺时针->右(1,0)右上(1,1)上(0,1)左上(-1,1)左(-1,0)左下(-1,-1)下(0,-1)右下(1,-1)
- int Sign[8][2] = { {1,0},{1,1},{0,1},{-1,1},{-1,0},{-1,-1},{0,-1},{1,-1} };
- int count = 0;//产生M个不同随机数
- int Random; //随机数1-100
- int x, y; //横纵坐标
- srand(unsigned(time(NULL)));
- //清空
- for (int i = 0; i < M; i++)
- for (int j = 0; j < N; j++)
- A[i][j] = 0;
- //把M个雷安放好
- while (count < M)
- {
- Random = rand() % 100 + 1;
- x = Random / 10; //转换为X
- y = Random - 10 * x; //转换为Y
- if (A[x][y] == 0) //地雷设为-1,无地雷设为0,1,2...
- {
- A[x][y] = -1;
- count++;
- }
- }
- //构建一个虚拟的地图即增加外围[M][N]->[M+2][N+2]目的是为了让边界和内部的处理方式一样
- int Virtual[M + 2][N + 2] = { 0 };
- for (int i = 0; i < M; i++)
- {
- for (int j = 0; j < N; j++)
- {
- Virtual[i + 1][j + 1] = A[i][j];//所有元素向下向右移动1格
- }
- }
- //计算每个地方的地雷分布情况
- for (int i = 1; i <= M; i++)
- {
- for (int j = 1; j <= N; j++)
- {
- int flag = 0;
- //如果是地雷
- if (Virtual[i][j] == -1)
- continue; //跳过
- for (int k = 0; k < 8; k++)
- {
- if (Virtual[i + Sign[k][0]][j + Sign[k][1]]==-1)
- flag++;
- }
- A[i-1][j-1] = flag;
- }
- }
- }
- void Map(int A[M][N],int Static[M][N])
- {
- system("cls");
- Welcome();
- //地雷用※表示,数字用123...,未翻开用■ Static[M][N]用于储存状态0表示未翻开,1表示翻开
- for (int i = 0; i < M; i++)
- {
- cout << "\t\t\t\t\t"<<" ";
- for (int j = 0; j < N; j++)
- {
- if (Static[i][j] == 0)
- cout << "■";
- else
- {
- if (A[i][j] == -1)
- {
- cout << "※";
- }
- else
- {
- if (IfSafety(A, i, j))
- cout << "□";
- else
- cout <<" " <<A[i][j];
- }
- }
- }
- cout << endl;
- }
- }
- void Operate(int A[M][N], int Static[M][N],int x,int y)//贪心算法
- {
- queue<P> que;//队列
- //从右开始顺时针->右(1,0)右上(1,1)上(0,1)左上(-1,1)左(-1,0)左下(-1,-1)下(0,-1)右下(1,-1)
- int Sign[8][2] = { {1,0},{1,1},{0,1},{-1,1},{-1,0},{-1,-1},{0,-1},{1,-1} };
- if (A[x][y] == -1) //如果翻到地雷,游戏结束
- {
- Result(A); //显示结果
- GameOver(); //游戏结束
- exit(0);
- }
- Static[x][y] = 1;//翻开
- que.push(P(x, y));
- while (que.size()) {
- P p = que.front();
- que.pop();
- if(!IfSafety(A, p.first, p.second))
- continue; //如果周围有炸弹,继续遍历队列
- for (int i = 0; i < 8; i++) {
- int nx = p.first + Sign[i][0];
- int ny = p.second + Sign[i][1];
- if (0 <= nx && nx < M && 0 <= ny && ny < N && Static[nx][ny] == 0) {
- que.push(P(nx, ny));
- Static[nx][ny] = 1;//翻开
- }
- }
- }
- }
- void Result(int A[M][N])
- {
- for (int i = 0; i < M; i++) {
- cout << "\t\t\t\t\t";
- for (int j = 0; j < N; j++)
- cout << A[i][j]<<" ";
- cout << endl;
- }
- }
- int IfSafety(int A[M][N],int x, int y)
- {
- //从右开始顺时针->右(1,0)右上(1,1)上(0,1)左上(-1,1)左(-1,0)左下(-1,-1)下(0,-1)右下(1,-1)
- int Sign[8][2] = { {1,0},{1,1},{0,1},{-1,1},{-1,0},{-1,-1},{0,-1},{1,-1} };
- int Virtual[M + 2][N + 2] = { 0 };
- x = x + 1;//虚拟坐标
- y = y + 1;
- for (int i = 0; i < M; i++)
- {
- for (int j = 0; j < N; j++)
- {
- Virtual[i + 1][j + 1] = A[i][j];//所有元素向下向右移动1格
- }
- }
- //计算每个地方的地雷分布情况
- for (int k = 0; k < 8; k++)
- {
- if (Virtual[x + Sign[k][0]][y + Sign[k][1]] == -1)
- return 0;
- }
- return 1;
- }
- void Welcome()
- {
- cout << "\t\t\t\t\t\t扫雷游戏"<<endl<<endl;
- cout << "\t\t\t\t===========================================" << endl << endl;
- gotoxy(40, 3);
- for (int i = 0; i < M; i++)
- {
- //画x轴坐标
- cout << " " << i + 1;
- }
- for (int j = 0; j < M; j++)
- {
- //画Y轴坐标
- gotoxy(38, 4+j);
- cout << j + 1<<endl;
- }
- gotoxy(0, 4);
- }
- void GameOver()
- {
- cout << "\t\t\t\t游戏结束,你输了" << endl;
- getchar();
- getchar();
- }
- void gotoxy(int x, int y)
- {
- COORD pos;
- pos.X = x;
- pos.Y = y;
- SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
- }
- void color(int c)
- {
- SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),c);
- }
主函数
- #include"Mine_Sweep.h"
- int main()
- {
- int A[M][N], x, y, Static[M][N] = { 0 };
- color(13);
- InitGame(A);
- cout << "\n\n\n\t\t游戏说明:" << "你需要在不点错雷的情况下尽可能快的将所有的雷都标记出来\n";
- cout << "\t\t你点出了一个数字,是1,就说明它周围的8的格子里有1个雷,是2就有两个雷,是3就有三个雷···" << endl;
- cout<< "\t\t但如果你标记错了雷,那就会boom!游戏结束。"<<endl;
- cout << "\t\t请先输入横坐标,再输入纵坐标 eg: 1 2" << endl;
- cout << "\t\t回车键开始,祝你好运!" << endl;
- getchar();
- color(15);
- while (1)
- {
- int flag = 1;
- Map(A, Static);
- cout << "\t\t\t\t请输入要翻开的坐标:";
- cin >> x >> y;
- while (x <= 0 || x > M || y <= 0 || y > N)
- {
- cout << "\t\t\t\t超出范围,请重新输入要翻开的坐标:" ;
- cin >> x >> y;
- }
- Operate(A, Static, x-1, y-1);
- }
- return 0;
- }
运行效果
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。
原文链接:https://blog.csdn.net/weixin_45710947/article/details/108687305