扫雷是一款经典的单人益智游戏,游戏规则是在一个方格矩阵中,随机分布一定数量的地雷,玩家需要依靠已知的数字提示,找出所有没有地雷的方格,而不触发任何地雷。

以下是一个用C语言实现的扫雷游戏的示例代码,其中用到了控制台界面和键盘输入:

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <time.h>
#include <windows.h>

#define WIDTH  10
#define HEIGHT 10
#define MINES  10

// 游戏状态
enum {GAME_PLAYING, GAME_WIN, GAME_LOSE};

// 地图
int map[HEIGHT][WIDTH];

// 游戏状态
int game_state;

// 绘制游戏界面
void draw_board()
{
    system("cls");
    printf("Minesweeper\n\n");
    printf("    ");
    for (int i = 0; i < WIDTH; i++) {
        printf("%d ", i);
    }
    printf("\n");
    printf("    ");
    for (int i = 0; i < WIDTH; i++) {
        printf("--");
    }
    printf("\n");
    for (int i = 0;; i < HEIGHT; i++) {
        printf("%2d |", i);
        for (int j = 0; j < WIDTH; j++) {
            if (map[i][j] == -1) {
                printf("* ");
            } else if (map[i][j] == 0) {
                printf(". ");
            } else {
                printf("%d ", map[i][j]);
            }
        }
        printf("\n");
        if (i == HEIGHT-1) {
            printf("    ");
            for (int i = 0; i < WIDTH; i++) {
                printf("--");
            }
            printf("\n");
            break;
        }
    }
}

// 随机生成地雷
void generate_mines(int first_x, int first_y)
{
    int count = 0;
    while (count < MINES) {
        int x = rand() % WIDTH;
        int y = rand() % HEIGHT;
        if (map[y][x] != -1 && (x != first_x || y != first_y)) {
            map[y][x] = -1;
            count++;
        }
    }
}

// 获取指定位置周围地雷数量
int get_mine_count(int x, int y)
{
    int count = 0;
    for (int i = y-1; i <= y+1; i++) {
        for (int j = x-1; j <= x+1; j++) {
            if (i >= 0 && i < HEIGHT && j >= 0 && j < WIDTH && map[i][j] == -1) {
                count++;
            }
        }
    }
    return count;
}

// 检查是否已经赢得游戏
int check_win()
{
    for (int i = 0; i < HEIGHT; i++) {
        for (int j = 0; j < WIDTH; j++) {
            if (map[i][j] >= 0 && map[i][j] <= 8) {
                if (map[i][j] != get_mine_count(j, i)) {
                    return 0;
                }
            }
        }
    }
    return 1;
}

// 开始游戏
void play_game(int first_x, int first_y)
{
    // 初始化地图
    for (int i = 0; i < HEIGHT; i++) {
        for (int j = 0; j < WIDTH; j++) {
            map[i][j] = 0;
        }
    }

    // 随机生成地雷
    generate_mines(first_x, first_y);

    // 计算周围地雷数量
    for (int i = 0; i < HEIGHT; i++) {
        for (int j = 0; j < WIDTH; j++) {
            if (map[i][j] != -1) {
                map[i][j] = get_mine_count(j, i);
            }
        }
    }

    // 游戏开始
    game_state = GAME_PLAYING;
    draw_board();

    while (game_state == GAME_PLAYING) {
        // 获取玩家输入
        int x, y;
        printf("Enter x and y (separated by space): ");
        scanf("%d %d", &x, &y);

        // 检查输入是否合法
        if (x < 0 || x >= WIDTH || y < 0 || y >= HEIGHT) {
            printf("Invalid input!\n");
            continue;
        }
        if (map[y][x] != 0) {
            printf("This cell has already been opened!\n");
            continue;
        }


         // 打开该位置
       if (map[y][x] == -1) {
           game_state = GAME_LOSE;
       } else {
           map[y][x] = get_mine_count(x, y);
           draw_board();
           if (check_win()) {
               game_state = GAME_WIN;
           }
       }
   }

  // 游戏结束
  draw_board();
  if (game_state == GAME_WIN) {
      printf("Congratulations! You win!\n");
  } else {
      printf("Game over!\n");
  }
}

int main()
{
    srand((unsigned int) time(NULL));

    int first_x, first_y;
    printf("Enter the first move (x and y separated by space): ");
    scanf("%d %d", &first_x, &first_y);

    play_game(first_x, first_y);

    return 0;
}

Minesweeper

0 1 2 3 4 5 6 7 8 9 
--------------------

0 | 0 0 0 0 0 0 0 0 0 0
1 | 0 . . . . . . . . .
2 | 0 . . . . . . . . .
3 | 0 . . . . . . . . .
4 | 0 . . . . . . . . .
5 | 0 . . . . . . . . .
6 | 0 . . . . . . . . .
7 | 0 . . . . . . . . .
8 | 0 . . . . . . . . .
9 | 0 . . . . . . . . .
--------------------
Enter x and y (separated by space): 1 1

2. 如果该位置是地雷,则游戏失败,输出失败信息,例如:

Minesweeper

0 1 2 3 4 5 6 7 8 9 
--------------------

0 | 0 0 0 0 0 0 0 0 0 0
1 | 0 * . . . . . . . .
2 | 0 . . . . . . . . .
3 | 0 . . . . . . . . .
4 | 0 . . . . . . . . .
5 | 0 . . . . . . . . .
6 | 0 . . . . . . . . .
7 | 0 . . . . . . . . .
8 | 0 . . . . . . . . .
9 | 0 . . . . . . . . .
--------------------
Game over!

3. 如果该位置不是地雷,则显示该位置周围的地雷数量,并将其标记为已经打开,例如:

Minesweeper

0 1 2 3 4 5 6 7 8 9 
--------------------

0 | 0 0 0 0 0 0 0 0 0 0
1 | 0 * 1 . . . . . . .
2 | 0 1 1 . . . . . . .
3 | 0 . . . . . . . . .
4 | 0 . . . . . . . . .
5 | 0 . . . . . . . . .
6 | 0 . . . . . . . . .
7 | 0 . . . . . . . . .
8 | 0 . . . . . . . . .
9 | 0 . . . . . . . . .
--------------------
Enter x and y (separated by space):

4. 如果玩家打开了所有没有地雷的方格,则游戏胜利,输出胜利信息,例如:

Minesweeper

0 1 2 3 4 5 6 7 8 9 
--------------------

0 | 0 0 0 0 0 0 0 0 0 0
1 | 0 * 1 0 0 0 0 0 0 0
2 | 0 1 1 0 0 0 0 0 0 0
3 | 0 1 0 0 0 0 0 0 0 0
4 | 0 1 1 1 0 0 0 0 0 0
5 | 0 0 0 1 1 0 0 0 0 0
6 | 0 0 0 0 1 1 1 0 0 0
7 | 0 0 0 0 0 0 1 1 1 0
8 | 0 0 0 0 0 0