#include<iostream>
#include<cstdlib>
#include<bitset>
#include<conio.h>
#include<time.h>
#include <windows.h>
#include<queue>
#include<algorithm>
using namespace std;
struct node{
int x, y;
};
int xx[9] = { 0, 0, 1, -1, 1, 1, -1, -1, 0 };
int yy[9] = { 1, -1, 0, 0, 1, -1, 1, -1, 0 };
int Map[50][50];
int vis[50][50];
int bfs_vis[50][50];
int mine_map[50][50];
int sum_mine_map[50][50];
int mark[50][50];
int pos[50][50];
int map_size;//地图大小
int mine_size;//地雷数目
bool game_status;//游戏状态
bool complete;//游戏完成状态
int posx, posy;//光标位置
void init();//初始化
void create_mine();//地雷生成
void create_sum_mine();//地雷统计
int count_mine(int x, int y);//地雷计算
bool complete_check();//游戏完成检测
void operate();//用户交互
void update_map();//地图更新
void bfs(int x, int y);
void open(int x, int y);//打开格子
int random();
void display(){
cout << endl << " ";
for (int i = 0; i < map_size; i++)cout << " " << i;
cout << endl;
for (int i = 0; i < map_size; i++){
for (int j = 0; j < map_size; j++){
if (j == 0)cout << i;
if (mine_map[i][j] == 0)cout << "■";
else cout << "◎";
}
cout << endl;
}
cout << endl;
}
int main(){
srand((int)time(0));
init();
update_map();
while (1){
operate();
update_map();
if (!game_status)break;
complete = complete_check();
if (complete)break;
}
display();
if (complete)cout << "GAME COMPLETE" << endl;
else cout << "GAME FILE" << endl;
return 0;
}
bool complete_check(){
for (int i = 0; i < map_size; i++){
for (int j = 0; j < map_size; j++){
if (mine_map[i][j] != 1){
if (Map[i][j] == 0)return false;
}
}
}
return true;
}
void create_sum_mine(){
for (int i = 0; i < map_size; i++){
for (int j = 0; j < map_size; j++){
sum_mine_map[i][j] = count_mine(i, j);
}
}
}
void update_map(){
system("CLS");
for (int i = 0; i < map_size; i++){
for (int j = 0; j < map_size; j++){
if (pos[i][j] == 1){
cout << "♀";
}
else if (mark[i][j] != 0){
cout << "★";
}
else if (Map[i][j] == 0){
cout << "■";
}
else{
if (sum_mine_map[i][j] == 0){
cout << "□";
}
else{
switch (sum_mine_map[i][j]){
case 1:cout << "①"; break;
case 2:cout << "②"; break;
case 3:cout << "③"; break;
case 4:cout << "④"; break;
case 5:cout << "⑤"; break;
case 6:cout << "⑥"; break;
case 7:cout << "⑦"; break;
case 8:cout << "⑧"; break;
}
}
}
}
cout << endl;
}
}
void find(int x, int y){
for (int i = 0; i < 8; i++){
int tx = x, ty = y;
tx += xx[i];
ty += yy[i];
if (tx >= 0 && tx < map_size&&ty >= 0 && ty < map_size){
Map[tx][ty] = 1;
}
}
}
bool bfs_check(int x, int y){
if (x < 0 || x >= map_size || y < 0 || y >= map_size)return false;
if (sum_mine_map[x][y] != 0 || bfs_vis[x][y] == 1)return false;
return true;
}
void bfs(int tx, int ty){
Map[tx][ty] = 1;
bfs_vis[tx][ty] = 1;
find(tx, ty);
queue<node>S;
node now, next;
now.x = tx;
now.y = ty;
S.push(now);
while (!S.empty()){
now = S.front();
S.pop();
for (int i = 0; i < 4; i++){
next = now;
next.x += xx[i];
next.y += yy[i];
if (bfs_check(next.x, next.y) == false)continue;
Map[next.x][next.y] = 1;
bfs_vis[next.x][next.y] = 1;
find(next.x, next.y);
S.push(next);
}
}
return;
}
void open(int x, int y){
if (mine_map[x][y] == 1){
game_status = false;
return;
}
else if (sum_mine_map[x][y] != 0){
Map[x][y] = 1;
}
else if (sum_mine_map[x][y] == 0){
bfs(x, y);
}
return;
}
void operate(){
cout << "wsad 上下左右 q打开 e标记 r取消标记" << endl;
char op = getch();
switch (op){
case 'w':{
if (posx - 1 >= 0){
pos[posx][posy] = 0;
posx--;
pos[posx][posy] = 1;
}
}break;
case 's':{
if (posx + 1 < map_size){
pos[posx][posy] = 0;
posx++;
pos[posx][posy] = 1;
}
}break;
case 'a':{
if (posy - 1 >= 0){
pos[posx][posy] = 0;
posy--;
pos[posx][posy] = 1;
}
}break;
case 'd':{
if (posy + 1 < map_size){
pos[posx][posy] = 0;
posy++;
pos[posx][posy] = 1;
}
}break;
case 'q':{
open(posx, posy);
}break;
case 'e':{
mark[posx][posy] = 1;
}break;
case 'r':{
mark[posx][posy] = 0;
}break;
default:break;
}
return;
}
int count_mine(int x, int y){
//地雷统计
int tx, ty, sum = 0;
for (int i = 0; i < 8; i++){
tx = x;
ty = y;
tx += xx[i];
ty += yy[i];
if (tx < 0 || tx >= map_size || ty < 0 || ty >= map_size)continue;
if (mine_map[tx][ty] == 1)sum++;
}
return sum;
}
void init(){
//初始化
game_status = true;
complete = false;
posx = posy = 0;
pos[posx][posy] = 1;
int level;
cout << "input level 1 2 3 or 0(自定义)";
cin >> level;
switch (level){
case 0:{
cout << "input map_size(地图大小<50) mine_size(地雷总数) "<<endl;
int x, y;
cin >> x >> y;
map_size = x;
mine_size = y;
}break;
case 1:{
map_size = 10;
mine_size = 15;
}break;
case 2:{
map_size = 15;
mine_size = 20;
}break;
case 3:{
map_size = 20;
mine_size = 25;
}break;
}
create_mine();
create_sum_mine();//地雷统计
}
void create_mine(){
//地雷生成
int count = mine_size, x, y;
while (count){
x = random();
y = random();
if (mine_map[x][y] == 0){
mine_map[x][y] = 1;
count--;
}
}
}
int random(){
while (1){
int x = rand() % map_size;
if (x >= 0)return x;
}
}