由于扫雷游戏的实现涉及到图形界面、事件处理等方面,本算法只提供一种基于控制台的简单实现方式。

  1. 定义游戏棋盘及雷区数组

使用二维数组定义游戏棋盘,其中每个元素表示一个方格,用数字表示该方格周围的雷数,-1表示该方格为雷。

int board[ROW][COL]; // 游戏棋盘,每个元素表示一个方格
int mine[ROW][COL]; // 雷区,-1表示该方格为雷,0表示非雷
  1. 初始化雷区

随机生成雷区,即在二维数组中随机选取若干个元素赋值为-1,表示该方格为雷。同时,计算每个非雷方格周围的雷数。

void initMine() {
    int i, j, k;
    // 初始化雷区
    memset(mine, 0, sizeof(mine));
    srand((unsigned int)time(NULL));
    for (i = 0; i < MINE_NUM; i++) {
        int x = rand() % ROW;
        int y = rand() % COL;
        if (mine[x][y] == -1) {
            i--;
            continue;
        }
        mine[x][y] = -1;
    }
    // 计算每个非雷方格周围的雷数
    for (i = 0; i < ROW; i++) {
        for (j = 0; j < COL; j++) {
            if (mine[i][j] == -1) continue;
            for (k = 0; k < 8; k++) {
                int x = i + dx[k];
                int y = j + dy[k];
                if (x >= 0 && x < ROW && y >= 0 && y < COL && mine[x][y] == -1) {
                    mine[i][j]++;
                }
            }
        }
    }
}
  1. 打印游戏棋盘

使用字符表示游戏棋盘,其中'*'表示未翻开的方格,'-'表示已翻开的空方格,“1-8”表示周围雷数,“X”表示已翻开的雷方格。

void printBoard() {
    int i, j;
    printf("  ");
    for (j = 0; j < COL; j++) {
        printf("%d ", j + 1);
    }
    printf("\n");
    for (i = 0; i < ROW; i++) {
        printf("%c ", 'A' + i);
        for (j = 0; j < COL; j++) {
            if (board[i][j] == -2) printf("* ");
            else if (board[i][j] == -1) printf("X ");
            else if (board[i][j] == 0) printf("- ");
            else printf("%d ", board[i][j]);
        }
        printf("\n");
    }
}
  1. 翻开指定方格

根据用户输入的坐标,翻开指定方格,如果该方格为雷,则游戏失败,否则更新游戏棋盘,并递归翻开周围的空方格。

void uncover(int x, int y) {
    if (board[x][y] != -2) return; // 已翻开或标记为雷的方格无法翻开
    if (mine[x][y] == -1) { // 翻开雷方格,游戏失败
        printf("BOOM! You lose.\n");
        board[x][y] = -1;
        printBoard();
        exit(0);
    }
    board[x][y] = mine[x][y];
    if (board[x][y] == 0) { // 翻开空方格,递归翻开周围的空方格
        int i;
        for (i = 0; i < 8; i++) {
            int nx = x + dx[i];
            int ny = y + dy[i];
            if (nx >= 0 && nx < ROW && ny >= 0 && ny < COL) {
                uncover(nx, ny);
            }
        }
    }
}
  1. 标记雷方格

根据用户输入的坐标,将指定方格标记为雷,如果已经标记为雷,则取消标记。

void mark(int x, int y) {
    if (board[x][y] == -2) board[x][y] = -3; // 标记为雷
    else if (board[x][y] == -3) board[x][y] = -2; // 取消标记
}
  1. 主函数

在主函数中依次调用上述函数,实现扫雷游戏的逻辑。

int main() {
    int i, j;
    char x, y;
    // 初始化游戏棋盘和雷区
    memset(board, -2, sizeof(board));
    initMine();
    // 开始游戏
    while (1) {
        printBoard();
        printf("Enter coordinate (row,column) or 'm' to mark a mine: ");
        scanf(" %c%c", &x, &y);
        if (x == 'm' || x == 'M') { // 标记雷方格
            scanf(" %c%c", &x, &y);
            mark(x - 'A', y - '1');
        } else { // 翻开方格
            uncover(x - 'A', y - '1');
        }
        // 判断游戏是否胜利
        int count = 0;
        for (i = 0; i < ROW; i++) {
            for (j = 0; j < COL; j++) {
                if (board[i][j] == -2 || board[i][j] == -3) {
                    count++;
                }
            }
        }
        if (count == MINE_NUM) {
            printf("Congratulations! You win.\n");
            printBoard();
            break;
        }
    }
    return 0;
}

说明:

  • 代码中 ROWCOLMINE_NUMdxdy 等变量需要根据实际情况进行定义。
  • 由于这是一个简单的控制台版本,用户需要手动输入坐标,没有图形界面。
  • 可以根据需要添加其他功能,例如游戏难度选择、计时器等。
C 语言扫雷游戏算法实现 - 基于控制台的简单方法

原文地址: https://www.cveoy.top/t/topic/n2EI 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录