// 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;
        }
    }
}
最后修改:2019 年 11 月 10 日
如果觉得我的文章对你有用,请随意赞赏