扫雷

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>
//1.打印一个菜单,提示用户是否开始游戏
int  Menu() {
	printf("##########################\n");
	printf("           1.play         \n");
	printf("           0.exit         \n");
	printf("##########################\n");
	int choice = 0;
	printf("请输入您的选择:\n");
	scanf("%d", &choice);
	return choice;
}
#define Mine_number 10
#define ROW 9
#define COL 9
//需要定义两个数组:(加一个边框)
//一个表示雷阵
//用字符'0'表示不是地雷,字符'1'表示是地雷
char mine_map[ROW + 2][COL + 2];

//一个表示给玩家展示的扫雷图
//*表示未打开的格子,打开的格子用具体的数字来表示周围8个格子地雷的数量
char show_map[ROW + 2][COL + 2];
//没有地雷的格子数
int no_mine_number = 0;
void Init(char mine_map[ROW+2][COL+2],char show_map[ROW+2][COL+2]) {
	//1.把数组进行初始化
	//把表示雷阵的数组全部初始化为'0'
	//(1)方法1:通过一个函数(对应参数的含义):需要进行赋值的数组名、需要赋值
	           //成什么、赋值区域的大小。
	memset(mine_map, '0', (ROW + 2)*(COL + 2));
	//(2)方法2:通过循环进行赋值
	//int row = 0;
	//int col = 0;
	//for (row = 1; row <= ROW; row++) {
	//	for (col = 1; col <= COL; col++) {
	//		mine_map[row][col] = '0';
	//	}
	//}
	//把表示未打开的格子全部初始化为*
   memset(show_map, '*', (ROW + 2)*(COL + 2));
	//2.通过随机的方法把雷阵布置好
   srand((unsigned)time(NULL));
   int mine_count = Mine_number;
   //每次随机产生一个横坐标、一个纵坐标,表示有地雷的位置,每次布置布置一个地雷
   //范围为:[1,ROW]
   while (mine_count > 0) {
	   int row = 0;
	   int col = 0;
	   row = rand() % 9 + 1;
	   col = rand() % 9 + 1;
	   if(mine_map[row][col] =='0'){
	   mine_map[row][col] = '1';
	   mine_count--;
	   }
   }
}
void PrintMap(char map[ROW + 2][COL + 2]) {
	int row = 0;
	int col = 0;
	//打印第一行之前先打印5个空格,为了让键盘更加好看
	printf("   ");
	//打印列号
	for (col = 1; col <= COL; col++) {
		printf("%d   ", col);
	}
	printf("\n");
	//打印第二行,边框
	for (col = 1; col <= COL; col++) {
		printf("----");
	}
	printf("\n");
	//打印具体内容
	for (row = 1; row <= ROW; row++) {
		//%02d的意思是把一位数也变为两位数输出
		//1==>01  2==>02
	//打印行号之前先打印一个空格,为了对其坐标与每个格子
	printf(" ");
		printf("%d|", row);
		for (col = 1; col <= COL; col++) {
			printf("%c   ", map[row][col]);
		}
		printf("\n");
		printf("\n");
	}
}
//需要统计当前位置周围8个位置的地雷数,并将结果更新到show_map中
void UpdateMap(char show_map[ROW + 2][COL + 2], char mine_map[ROW+2][COL+2],
	int row,int col ) {
	int mine_count = 0;
	//row, col;当前位置
	//1.row - 1, col - 1;
	//由于mine_map中只有两种情况,要么是1表示有地雷,要么是0表示没有地雷,
	//所以可以通过这种方式进行统计地雷的数量
	mine_count = (mine_map[row - 1][col - 1]-'0')+
	//2.row - 1, col;
	(mine_map[row - 1][col]-'0')+
	//3.row - 1, col + 1;
	(mine_map[row - 1][col + 1]-'0')+
	//4.row, col - 1;
	(mine_map[row][col - 1]-'0')+
	//5.row, col + 1;
	(mine_map[row][col + 1]-'0')+
	//6.row + 1, col - 1;
	(mine_map[row + 1][col - 1]-'0')+
	//7.row + 1, col;
	(mine_map[row + 1][col]-'0')+
	//8.row + 1, col + 1;
	(mine_map[row + 1][col + 1]-'0');
	show_map[row][col] = '0' + mine_count;//直接把地雷的数量转化为字符形式
	//表示出来。因为show_map[row][col]是字符类型的,字符'0'的ASCII码为60,'1'
	//的ASCII码为61,所以加几就转化为字符几的ASCII码。
}
void Game() {
	//1.初始化地图(mine_map,show_map)
	Init(mine_map, show_map);
	//2.先打印show_map.
	PrintMap(show_map);
	//因为涉及到后面的步骤需要判断是或否,有终止条件,所以此处需要循环
	while (1) {
	//3.提示用户输入坐标
		int row = 0;
		int col = 0;
	printf("请输入需要翻开方块的坐标:row col\n");
	scanf("%d %d", &row, &col);
	//4.对用户输入的合法性进行判断,如果不合理,提示用户重新输入
	if (row <= 0 || row > ROW || col <= 0 || col > COL) {
		printf("您的输入不合理请重新输入:\n");
		continue;
	}
	//5.判定玩家当前是否踩雷,如果踩雷,游戏结束并且打印雷阵
	if (mine_map[row][col] == '1') {
		printf("游戏结束!\n");
		PrintMap(mine_map);
		break;
	}
	//6.如果没踩雷,判定玩家是否胜利(胜利的条件是:已经翻开的方块数=总数-雷数)
	if (no_mine_number == ROW * COL - Mine_number) {
		printf("恭喜您获胜了!\n");
		PrintMap(mine_map);
		break;
	}
	//7.接下来就需要统计当前位置周围有几个雷,然后回到第3步
	UpdateMap(show_map,mine_map,row,col);
	PrintMap(show_map);
	}
}
//2.通过返回值判断是否进行游戏
void statr() {
	while (1) {
		int choice = Menu();
		if(choice==0){
			printf("退出游戏\n");
			break;
		}
	Game();//为1就调用该函数开始游戏
	break;//加这个break是为了让程序只进行一次,不管最后结果是赢还是输都退出
	      //游戏。
	}
}
int main() {
	statr();
	system("pause");
	return 0;
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值