简单扫雷

1.简单的扫雷,99的方格,为了数周围有几个雷,和后面加强翻开范围定义了2个+2的二维数组。
2.10个雷,为了随机布置雷,定义了宏#define MINE_COUNT 10,布置一个雷,- -MINE_COUNT,直到其为0。
3.int g_mine_count = MINE_COUNT;是为了显示玩家认为还有几个雷,标记一个- -;取消一个++。当其为10时无法取消,为0时无法标记。
4.加强翻开范围是先判断从(row,col)周围的3
3是否符合标准,周围还有‘ ’递归。

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>
#define ROW 9
#define COL 9
#define MINE_COUNT 10
int g_mine_count = MINE_COUNT;
//菜单
int menu(){
	printf("_____________________________\n");
	printf("1.开始游戏。\n");
	printf("2.退出游戏。\n");
	printf("_____________________________\n");
	int choice;
	printf("请输入你的选择:");
	scanf("%d", &choice);
	return choice;
}
//检查格子周围有几个雷
char check1(char mine_map[ROW + 2][COL + 2], int row, int col){
	char num = '0';
	for (int a = row - 1; a <= row + 1; a++){
		for (int b = col - 1; b <= col + 1; b++){
			if (mine_map[a][b] == 'X'){
				num++;
			}
		}
	}
	if (num == '0'){
		return ' ';
	}
	return num;
}
//初始化二维数组
void Init(char show_map[ROW + 2][COL + 2],
	char mine_map[ROW + 2][COL + 2]){
	memset(show_map, '*', (ROW + 2)*(COL + 2));
	memset(mine_map, ' ', (ROW + 2)*(COL + 2));
	//布置雷
	int mine_count = MINE_COUNT;
	while (mine_count>0){
		int row = rand() % ROW + 1;
		int col = rand() % COL + 1;
		if (mine_map[row][col] != ' '){
			continue;
		}
		mine_map[row][col] = 'X';
		mine_count--;
	}
	//让所有格子显示周围有多少个雷
	for (int row = 1; row < ROW + 1; row++){
		for (int col = 1; col < COL + 1; col++){
			if (mine_map[row][col] != 'X'){
				mine_map[row][col] = check1(mine_map, row, col);
			}
		}
	}
}
//检查是否翻完
int check2(char show_map[ROW + 2][COL + 2],
	char mine_map[ROW + 2][COL + 2]){
	for (int row = 1; row < ROW + 1; row++){
		for (int col = 1; col < COL + 1; col++){
			if (show_map[row][col] != mine_map[row][col] &&
				mine_map[row][col] != 'X'){
				return 0;
			}
		}
	}
	return 1;
}
//踩雷后,把雷赋予显示给玩家看的数组
void dispianymap(char show_map[ROW + 2][COL + 2],
	char mine_map[ROW + 2][COL + 2]){
	for (int row = 1; row < ROW + 1; row++){
		for (int col = 1; col < COL + 1; col++){
			if (mine_map[row][col] == 'X'){
				show_map[row][col] = mine_map[row][col];
			}
		}
	}
}
//显示地图
void updateshowmap(char map[ROW + 2][COL + 2]){
	printf("             还有%d个雷!\n", g_mine_count);
	printf("    1   2   3   4   5   6   7   8   9\n");
	printf("   ___________________________________\n");
	for (int row = 1; row < ROW + 1; row++){
		printf("%d ", row);
		printf("| %c | %c | %c | %c | %c | %c | %c | %c | %c |\n",
			map[row][1], map[row][2], map[row][3], map[row][4],
			map[row][5], map[row][6], map[row][7], map[row][8],
			map[row][9]);
		printf("  |___|___|___|___|___|___|___|___|___|\n");
	}
}
//加强翻开的范围
void game_open2(char show_map[ROW + 2][COL + 2],
	char mine_map[ROW + 2][COL + 2], int row, int col){
	for (int a = row - 1; a <= row + 1; a++){
		for (int b = col - 1; b <= col + 1; b++){
			if (a<1 || a>ROW || b<1 || b>COL){
				continue;
			}
			if (show_map[a][b] == mine_map[a][b]){
				continue;
			}
			if (mine_map[a][b] == 'X'){
				continue;
			}
			if (mine_map[a][b] != ' '){
				show_map[a][b] = mine_map[a][b];
				continue;
			}
			show_map[a][b] = mine_map[a][b];
			game_open2(show_map, mine_map, a, b);
		}
	}
}
//翻开坐标
int game_open(char show_map[ROW + 2][COL + 2],
	char mine_map[ROW + 2][COL + 2]){
	while (1){
		int row = 0;
		int col = 0;
		printf("请玩家输入选择要翻开的坐标(row col):");
		scanf("%d %d", &row, &col);
		if (row<1 || row>ROW || col<1 || col>COL){
			printf("输入非法!请重新输入。\n");
			continue;
		}
		if (show_map[row][col] == '!'){
			printf("你选择的位置已经标记!请重新输入。\n");
			continue;
		}
		if (show_map[row][col] != '*'){
			printf("你选择的位置已经翻开!请重新输入。\n");
			continue;
		}
		if (mine_map[row][col] == 'X'){
			dispianymap(show_map, mine_map);
			updateshowmap(show_map);
			printf("你踩到雷了。游戏结束!\n");
			return 0;
		}
		if (mine_map[row][col] == ' '){
			game_open2(show_map, mine_map, row, col);
			return 1;
			break;
		}
		show_map[row][col] = mine_map[row][col];
		if (check2(show_map, mine_map) != 0){
			updateshowmap(mine_map);
			printf("你扫完了所有雷,游戏结束!\n");
			return 0;
			break;
		}
		return 1;
		break;
	}
}
//标记雷
void game_sign(char show_map[ROW + 2][COL + 2],
	char mine_map[ROW + 2][COL + 2]){
	while (1){
		int row = 0;
		int col = 0;
		printf("请玩家输入选择要标记的坐标(row col):");
		scanf("%d %d", &row, &col);
		if (row<1 || row>ROW || col<1 || col>COL){
			printf("输入非法!请重新输入。\n");
			continue;
		}
		if (show_map[row][col] == '!'){
			printf("你选择的位置已经标记!请重新输入。\n");
			continue;
		}
		if (show_map[row][col] != '*'){
			printf("你选择的位置已经翻开!请重新输入。\n");
			continue;
		}
		show_map[row][col] = '!';
		g_mine_count--;
		break;
	}
}
//取消标记
void game_cancel(char show_map[ROW + 2][COL + 2],
	char mine_map[ROW + 2][COL + 2]){
	while (1){
		int row = 0;
		int col = 0;
		printf("请玩家输入选择要取消标记的坐标(row col):");
		scanf("%d %d", &row, &col);
		if (row<1 || row>ROW || col<1 || col>COL){
			printf("输入非法!请重新输入。\n");
			continue;
		}
		if (show_map[row][col] != '!'){
			printf("你选择的位置没有标记!请重新输入。\n");
			continue;
		}
		show_map[row][col] = '*';
		g_mine_count++;
		break;
	}
}
//游戏过程
void game(){
	char show_map[ROW + 2][COL + 2];
	char mine_map[ROW + 2][COL + 2];
	Init(show_map, mine_map);
	while (1){
		updateshowmap(show_map);
		printf("______________\n");
		printf("1.翻开。\n");
		printf("2.标记。\n");
		printf("3.取消。\n");
		printf("______________\n");
		int choice = 0;
		printf("请选择:");
		scanf("%d", &choice);
		if (choice == 1){
			int isover=game_open(show_map, mine_map);
			if (isover==0){
				break;
			}
		}
		else if (choice == 2){
				if (g_mine_count == 0){
				   printf("你标记的雷超出上限无法标记,请重新选择!\n");
				  continue;
			}
			game_sign(show_map, mine_map);
		}
		else if (choice == 3){
			if (g_mine_count == 10){
				printf("没有标记,无法取消,请重新选择!\n");
				continue;
			}
			game_cancel(show_map, mine_map);
		}
		else{
			printf("输入非法,请重新输入!\n");
		}
	}
}
int main(){
	srand((unsigned int)time(0));
	while (1){
		int choice = menu();
		if (choice == 1){
			game();
			continue;
		}
		else if (choice == 2){
			printf("欢迎你的下次使用!\n");
			break;
		}
		else{
			printf("输入非法,请重新输入!\n");
		}
	}
	system("pause");
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值