// mine.h
// ------
#define _CRT_SECURE_NO_WARNINGS
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <Windows.h>
#define ROW 9
#define COL 9
#define MINE_COUNT 10
int Menu();
void mapInit(char mine_map[ROW][COL], char show_map[ROW][COL]);
void print_map(char map[ROW][COL]);
int check_win(char show_map[ROW][COL]);
void update_map(char show_map[ROW][COL], char mine_map[ROW][COL],
int row, int col);
void game();
void PlayNow();
// mine.c
// ------
#include "mine.h"
int Menu() {
int choice = -1;
printf("-----------------------------------\n");
printf(" 1. 开始游戏 \n");
printf(" 2. 退出程序 \n");
printf("-----------------------------------\n");
printf("请输入选项:");
scanf("%d", &choice);
return choice;
}
void mapInit(char mine_map[ROW][COL], char show_map[ROW][COL]) {
int mine_count = 0;
int row, col;
// 初始化mine_map
for (int i = 0; i < ROW; i++) {
for (int j = 0; j < COL; j++) {
mine_map[i][j] = '0';
}
}
while (mine_count < MINE_COUNT) {
row = rand() % 9;
col = rand() % 9;
if (mine_map[row][col] == '1')
continue;
mine_map[row][col] = '1';
mine_count++;
}
// 初始化show_map
for (int i = 0; i < ROW; i++) {
for (int j = 0; j < COL; j++) {
show_map[i][j] = '*';
}
}
}
void print_map(char map[ROW][COL]) {
// 打印第一行
printf(" | ");
for (int i = 0; i < ROW; i++) {
printf("%d ", i);
}
printf("\n");
// 打印一条横线
for(int i = 0; i < ROW - 1; i++)
printf("---");
printf("\n");
// 打印剩余行
for (int i = 0; i < ROW; i++) {
printf(" %d | ", i);
for (int j = 0; j < COL; j++) {
printf("%c ", map[i][j]);
}
printf("\n");
}
}
// 1表示赢了 0表示没赢
int check_win(char show_map[ROW][COL]) {
int blank_count = 0;
// 如果只剩一个空地没翻开,那么这次一定就翻的是这个空地
for (int i = 0; i < ROW; i++) {
for (int j = 0; j < COL; j++) {
if (show_map[i][j] == '*')
blank_count++;
}
}
if (blank_count == MINE_COUNT + 1)
return 1;
else {
return 0;
}
}
void update_map(char show_map[ROW][COL], char mine_map[ROW][COL],
int row, int col) {
int mine_count = 0;
// 计算周围8个格子有几个雷
if (row - 1 >= 0 && col - 1 >= 0 && mine_map[row - 1][col - 1] == '1')
mine_count++;
if (row - 1 >= 0 && mine_map[row - 1][col] == '1')
mine_count++;
if (row - 1 >= 0 && col + 1 < ROW && mine_map[row - 1][col + 1] == '1')
mine_count++;
if (col - 1 >= 0 && mine_map[row][col - 1] == '1')
mine_count++;
if (col + 1 < COL && mine_map[row][col + 1] == '1')
mine_count++;
if (row + 1 < ROW && col - 1 >= 0 && mine_map[row + 1][col - 1] == '1')
mine_count++;
if (row + 1 < ROW && mine_map[row + 1][col] == '1')
mine_count++;
if (row + 1 < ROW && col + 1 < COL && mine_map[row + 1][col + 1] == '1')
mine_count++;
show_map[row][col] = mine_count + '0';
if (mine_count == 0) {
if(row - 1 >= 0 && show_map[row-1][col] == '*')
update_map(show_map, mine_map, row - 1, col);
if(row + 1 < ROW && show_map[row + 1][col] == '*')
update_map(show_map, mine_map, row + 1, col);
if(col - 1 >= 0 && show_map[row][col - 1] == '*')
update_map(show_map, mine_map, row, col - 1);
if(col + 1 < COL && show_map[row][col + 1] == '*')
update_map(show_map, mine_map, row, col + 1);
}
}
void game() {
char mine_map[ROW][COL];
char show_map[ROW][COL];
int row, col;
// 初始化两个map
mapInit(mine_map, show_map);
// 开始游戏
while (1) {
print_map(show_map);
print_map(mine_map);
printf("请输入坐标(row col):");
scanf("%d %d", &row, &col);
// 判断坐标合法性
if (row < 0 || row >= ROW || col < 0 || col >= COL) {
printf("您输入的坐标有误,请重新输入!\n");
Sleep(1000);
system("cls");
continue;
}
else if (show_map[row][col] != '*') {
printf("您输入的坐标已翻开,请重新输入!\n");
Sleep(1000);
system("cls");
continue;
}
// 判断是否是雷
if (mine_map[row][col] == '1') {
printf("Game Over!!!\n");
print_map(show_map);
print_map(mine_map);
return;
}
// 判断是否已经赢了
if (check_win(show_map)) {
printf("你赢了!!!\n");
print_map(mine_map);
return;
}
// 翻开这个位置并且递归翻开周围
update_map(show_map, mine_map, row, col);
}
}
void PlayNow() {
int choice;
srand((unsigned int)time(0)); // 设置种子
while (1) {
choice = Menu();
if (choice == 1) {
Sleep(200);
system("cls");
game();
system("pause");
}
else if (choice == 2) {
exit(0);
}
else {
printf("输入错误,请重新输入");
Sleep(500);
printf("!");
Sleep(500);
printf("!");
Sleep(500);
printf("!");
Sleep(500);
system("cls");
continue;
}
}
}