C语言扫雷小游戏-LMLPHP

以下是一个简单的C语言扫雷小游戏的示例代码:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4. #define BOARD_SIZE 10
  5. #define NUM_MINES 10
  6. int main() {
  7.     int board[BOARD_SIZE][BOARD_SIZE];
  8.     int num_flags, num_clicks;
  9.     int row, col;
  10.     int reveal[BOARD_SIZE][BOARD_SIZE];
  11.     int mines_left;
  12.     int won;
  13.     char action;
  14.     srand(time(NULL)); // 初始化随机数生成器
  15.     // 初始化雷区,标记雷区中的雷数和未标记的雷数
  16.     for (int i = 0; i < BOARD_SIZE; i++) {
  17.         for (int j = 0; j < BOARD_SIZE; j++) {
  18.             board[i][j] = 0; // 初始化为空格
  19.             reveal[i][j] = 0; // 初始化为未揭示状态
  20.         }
  21.     }
  22.     num_flags = 0; // 初始化为未标记的雷数为0
  23.     mines_left = NUM_MINES; // 初始化为还有NUM_MINES个雷未被标记
  24.     won = 0; // 初始化为游戏未获胜状态
  25.     // 在随机位置放置雷区中的雷
  26.     while (mines_left > 0) {
  27.         row = rand() % BOARD_SIZE; // 随机选择行号
  28.         col = rand() % BOARD_SIZE; // 随机选择列号
  29.         if (board[row][col] != -1) { // 如果该位置不是已经被标记为雷的位置,则将该位置标记为雷,并更新mines_left和board数组
  30.             board[row][col] = -1;
  31.             mines_left--;
  32.         } else { // 如果该位置已经被标记为雷,则重新选择位置
  33.             continue;
  34.         }
  35.         num_flags++; // 更新已标记的雷数
  36.     }
  37.     // 游戏主循环,直到游戏获胜或玩家选择退出游戏为止
  38.     while (1) {
  39.         printf("\n\n"); // 输出一个空行,使输出更清晰
  40.         printf("Minefield:\n"); // 输出雷区名称和当前已标记的雷数和剩余的雷数
  41.         printf("F-revealed, flags: %d/%d\n", num_flags, BOARD_SIZE * BOARD_SIZE); // 输出已揭示的方块数和总方块数
  42.         printf("C-click, Q-quit, X-flag\n"); // 输出操作提示信息,C表示点击方块,Q表示退出游戏,X表示标记方块为雷
  43.         printf("\n"); // 输出一个空行,使输出更清晰
  44.         for (int i = 0; i < BOARD_SIZE; i++) { // 输出雷区表格,0表示空格,-1表示雷,'#'表示已揭示的雷,'.'表示未揭示的空格,'F'表示已标记的雷
  45.             for (int j = 0; j < BOARD_SIZE; j++) {
  46.                 if (board[i][j] == -1) { // 如果该位置是雷,则输出'#'并更新reveal数组中对应位置的状态为1(已揭示)和更新num_flags和num_clicks的值(点击了已揭示的雷)
  47.                     printf("#");
  48.                     reveal[i][j] = 1; // 将该位置揭示为雷区中的雷

示),否则输出board[i][j]的值(0或-1)

        }

    }

    printf("\n"); // 输出一个空行,使输出更清晰

    scanf(" %c", &action); // 获取玩家操作

    if (action == 'c') { // 如果玩家选择点击方块

        printf("Click: ");

        scanf("%d %d", &row, &col); // 获取玩家点击的方块位置

        if (board[row][col] == 0) { // 如果该位置是空格,则将该位置揭示为雷或空格,并输出相应信息

            board[row][col] = 1;

            reveal[row][col] = 1;

            if (num_clicks == BOARD_SIZE * BOARD_SIZE - mines_left) { // 如果玩家已经点击了所有非雷的方块,则游戏获胜,跳出循环

                won = 1;

                break;

            }

        } else if (board[row][col] == -1) { // 如果该位置是雷,则游戏失败,跳出循环

            won = -1;

            break;

        } else { // 如果该位置已经被揭示为雷或空格,则不进行任何操作,继续等待玩家输入下一个操作

            continue;

        }

        num_clicks++; // 更新已点击的方块数

    } else if (action == 'q') { // 如果玩家选择退出游戏,则跳出循环

        won = 0;

        break;

    } else if (action == 'x') { // 如果玩家选择标记方块为雷

        printf("Flag: ");

        scanf("%d %d", &row, &col); // 获取玩家标记的方块位置

        if (board[row][col] != -1 && reveal[row][col] == 0) { // 如果该位置是空格且未被揭示,则将该位置标记为雷,并输出相应信息

            board[row][col] = -1;

            reveal[row][col] = 1;

            num_flags++; // 更新已标记的雷数

        } else { // 如果该位置是雷或已经被揭示,则不进行任何操作,继续等待玩家输入下一个操作

            continue;

        }

    } else { // 如果玩家输入的操作不是合法的,则提示玩家重新输入,并等待一段时间后自动回到游戏主循环开始下一轮操作

        printf("Invalid action. Please try again.\n");

        usleep(1000000); // 等待一段时间,使程序运行更流畅,避免频繁输入导致程序卡顿

        continue;

    }

    if (won != 0) { // 如果游戏获胜或失败,输出相应信息,并等待一段时间后自动退出程序

        printf("Game over! You %s!\n", won == 1 ? "won" : "lost");

        usleep(1000000); // 等待一段时间,使程序运行更流畅,避免频繁输入导致程序卡顿

        break;

    }

}

这段代码实现了基本的扫雷游戏逻辑,玩家可以通过输入“C”来点击方块,输入“Q”来退出游戏,输入“X”来标记方块为雷。点击空格会揭示该位置为雷或空格,点击雷会导致游戏失败。当玩家已经点击了所有非雷的方块时,游戏获胜。游戏过程中,会随机生成雷区中的雷,并提示玩家当前已标记的雷数和剩余的雷数。当游戏结束后,会输出游戏结果。

注意,该代码仅供参考,可以根据需要进行修改和优化。同时,还需要考虑一些边界情况和错误处理,以确保程序的正确性和健壮性。

确实,这个简单的扫雷实现还没有包含一些高级功能,比如:无法标记已经被标记为雷的方块,没有提供撤销操作,游戏结束后无法重新开始等。同时,这个程序也没有处理输入错误的情况,比如:玩家输入了无效的操作。

下面是对这段代码的一些改进建议:

  1. 增加错误处理:当玩家输入了无效的操作时,程序应该能够捕获这个错误,并提示玩家重新输入。可以使用switch语句来处理不同的操作。
  2. 添加撤销操作:玩家应该有机会撤销他们最近的点击或标记操作。这可以通过在boardreveal数组中相应地更新来实现。
  3. 防止重复标记:玩家不应该能够标记已经被标记为雷的方块。可以在标记操作中增加一个检查,以确保玩家没有标记已经被标记的方块。
  4. 增加游戏结束后的选项:游戏结束后,玩家可以选择退出或者重新开始游戏。可以通过添加一个全局变量来跟踪游戏的状态,并在游戏结束后询问玩家的意愿。
  5. 优化布局和输出:当前的输出布局可能会有些混乱,特别是当游戏的规模变得很大的时候。可以考虑使用表格或者其他格式来更清晰地显示游戏状态。
  6. 增加难度等级:可以根据玩家的表现来调整游戏的难度,比如:随机生成更多的雷,或者增加每轮的操作次数等。
  7. 增加音效和图形界面:为了使游戏更加吸引人,可以添加音效和图形界面。这可能需要使用额外的库,比如:SDL或者Allegro。

这些只是一些基本的改进建议,你可以根据自己的需求和喜好来调整这个程序。

12-07 11:57