#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define ROW 9
#define COL 9
#define MINE_COUNT 10
//9*9的格子
int Menu() {
printf("======================\n");
printf(" 1.开始游戏 \n ");
printf(" 0.退出游戏 \n");
printf("======================\n");
printf("请输入您的选择:");
int choice;
scanf("%d\n", &choice);
return choice;
}
//初始化
void Init(char mine_map[ROW + 2][COL + 2], char show_map[ROW + 2][COL + 2]) {
//show_map全都初始化为'*'(用*表示未被翻开的位置)
//mine_map先全部初始化为'0'
//对mine_map进行类真的布置
for (int row = 0; row < ROW + 2; ++row) {
for (int col = 0; col < COL + 2; ++col) {
show_map[row][col] = '*';
}
}
for (int row = 0; row < ROW + 2; ++row) {
for (int col = 0; col < COL + 2; ++col) {
mine_map[row][col] = '0';
}
}
int mine_count = MINE_COUNT;
while (mine_count>0) {
//这个循环尝试进行布雷,每次布置成功一个雷,mine_count--
int row = rand() % 9 + 1;
int col = rand() % 9 + 1;
if (mine_map[row][col] == '1') {
continue;
}
//当前位置可以用来设置地雷
mine_map[row][col] = '1';
--mine_count;
}
return;
}
void DisplayMap(char map[ROW + 2][COL + 2]) {
//先打印四个空格
printf(" ");
//打印列的坐标[1,COL]
for (int i = 1; i <= COL; ++i) {
printf("%d", i);
}
printf("\n"); //第一行打印完成了
//从这里打印边框
for (int i = 1; i <= COL; ++i) {
printf("---");
}
printf("\n");
//打印棋盘的每一行,每一行最前面带上行号
for (int row = 1; row <= ROW; ++row) {
printf(" %d|", row);
for (int col = 1; col <= COL; ++col) {
printf("%c ", map[row][col]);
}
printf("\n");
}
}
void UpdateShowMap(char mine_map[ROW + 2][COL + 2],
char show_map[ROW+2][COL+2], int row, int col) {
//每翻开一个格子时,入股这个格子不是雷,需要更新show_map
int mine_count =
(mine_map[row - 1][col - 1] - '0')
+ (mine_map[row - 1][col] - '0')
+ (mine_map[row - 1][col + 1] - '0')
+ (mine_map[row][col - 1] - '0')
+ (mine_map[row][col + 1] - '0')
+ (mine_map[row + 1][col - 1] - '0')
+ (mine_map[row + 1][col - 1] - '0')
+ (mine_map[row + 1][col - 1] - '0');
show_map[row][col] = mine_count + '0';
//由于show_map中都是字符,需要把数字转为字符
}
void Game() {
//1.设定一个二维数组作为表示地雷的地图,'0'表示无雷,'1'表示有雷。
//2.设定一个二维数组作为表示给玩家看的地图。
char mine_map[ROW + 2][COL + 2];
char show_map[ROW + 2][COL + 2];
//+2相当于加了个边框
//3.对地图进行初始化
Init(mine_map, show_map);
int blank_not_mine_count = 0;
//打印初始地图
DisplayMap(show_map);
//4.提示玩家输入一组坐标,并对输入坐标的合法性进行检查
while (1) {
printf("请输入坐标(row col):");
int row = 0;
int col = 0;
scanf("%d %d", &row, &col);
//row,col有效范围[1,ROW],[1,COL]注意地图上有边框
if (row<1 || row>ROW || col<1 || col > COL) {
printf("您输入的坐标非法,请重新输入!\n");
continue;
}
//5.判断玩家翻开是否为地雷,如果是地雷游戏结束
if (mine_map[ROW][COL] == '1') {
printf("您踩雷了,游戏结束!");
//玩家踩雷的时候,需要告诉玩家哪些位置是地雷
DisplayMap(mine_map);
break;
}
//6.如果把最后一个不是雷的位置翻开了,游戏结束,玩家胜
++blank_not_mine_count;
if (blank_not_mine_count == ROW * COL - MINE_COUNT) {
printf("扫雷成功!\n");
DisplayMap(mine_map);
break;
}
//7.把这个位置翻开,并计算这个位置周围有几个雷
UpdateShowMap(mine_map,show_map,row,col);
DisplayMap(show_map);
}
}
int main() {
while (1) {
int choice = Menu();
if (choice == 1) {
Game();
}
else {
printf("goodbye!\n");
break;
}
}
system("pause");
return 0;
}