c语言实现扫雷

#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;
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值