扫雷游戏:C++ 代码实现及优化

题目描述

扫雷游戏是一款十分经典的单机小游戏。在 $n$ 行 $m$ 列的雷区中有一些格子含有地雷(称之为地雷格),其他格子不含地雷(称之为非地雷格)。玩家翻开一个非地雷格时,该格将会出现一个数字——提示周围格子中有多少个是地雷格。游戏的目标是在不翻出任何地雷格的条件下,找出所有的非地雷格。 现在给出 $n$ 行 $m$ 列的雷区中的地雷分布,要求计算出每个非地雷格周围的地雷格数。 注:一个格子的周围格子包括其上、下、左、右、左上、右上、左下、右下八个方向上与之直接相邻的格子。

输入格式

从标准输入读入数据。 输入第一行是用一个空格隔开的两个整数 $n$ 和 $m$,分别表示雷区的行数和列数。接下来 $n$ 行,每行 $m$ 个字符,描述了雷区中的地雷分布情况。字符 * 表示相应格子是地雷格,字符 ? 表示相应格子是非地雷格。相邻字符之间无分隔符。

输出格式

输出到标准输出。 输出包含 $n$($1 \le n \le 100$) 行,每行 $m$($1 \le m \le 100$) 个字符,描述整个雷区。用 * 表示地雷格,用周围的地雷个数表示非地雷格。相邻字符之间无分隔符。

样例 #1

样例输入 #1

3 3
*??
???
?*?

样例输出 #1

*10
221
1*1

代码实现

#include <iostream>
using namespace std;

const int N = 110;
char g[N][N];
int n, m;

int main()
{
    cin >> n >> m;
    for (int i = 0; i < n; i ++ ) cin >> g[i];

    int dx[8] = {-1, -1, -1, 0, 0, 1, 1, 1}, dy[8] = {-1, 0, 1, -1, 1, -1, 0, 1};
    for (int i = 0; i < n; i ++ )
        for (int j = 0; j < m; j ++ )
            if (g[i][j] == '?')
            {
                int cnt = 0;
                for (int k = 0; k < 8; k ++ )
                {
                    int x = i + dx[k], y = j + dy[k];
                    if (x < 0 || x >= n || y < 0 || y >= m) continue;
                    if (g[x][y] == '*') cnt ++ ;
                }
                g[i][j] = cnt + '0';
            }

    for (int i = 0; i < n; i ++ ) puts(g[i]);

    return 0;
}

代码优化

  1. 使用更直观的变量名: 代码中使用了 dxdy 数组来表示方向,但可以改为 directionXdirectionY,使代码更加易懂。
  2. 使用枚举类型: 可以使用枚举类型来表示方向,使代码更加清晰、可读性更高。
  3. 优化循环: 可以使用 for (auto &row : g) 这样的语法来遍历二维数组,使代码更加简洁。

优化后的代码

#include <iostream>
using namespace std;

const int N = 110;
char g[N][N];
int n, m;

int main()
{
    cin >> n >> m;
    for (auto &row : g) cin >> row;

    enum Direction { UP_LEFT, UP, UP_RIGHT, LEFT, RIGHT, DOWN_LEFT, DOWN, DOWN_RIGHT };
    int directionX[8] = {-1, -1, -1, 0, 0, 1, 1, 1}, directionY[8] = {-1, 0, 1, -1, 1, -1, 0, 1};
    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++)
            if (g[i][j] == '?')
            {
                int cnt = 0;
                for (Direction direction = UP_LEFT; direction <= DOWN_RIGHT; direction = static_cast<Direction>(direction + 1))
                {
                    int x = i + directionX[static_cast<int>(direction)], y = j + directionY[static_cast<int>(direction)];
                    if (x < 0 || x >= n || y < 0 || y >= m) continue;
                    if (g[x][y] == '*') cnt++;
                }
                g[i][j] = cnt + '0';
            }

    for (auto &row : g) puts(row);

    return 0;
}

总结

本文详细介绍了扫雷游戏的 C++ 代码实现,并对代码进行了优化,使代码更加易读、易懂,同时提高了代码的效率。希望本文对读者理解扫雷游戏的算法和编程实现有所帮助。

其他优化建议

  1. 使用更快的输入输出方式:可以考虑使用 cin.tie(nullptr)ios::sync_with_stdio(false) 来加速输入输出。
  2. 使用更高效的数据结构:对于大型的雷区,可以考虑使用其他数据结构,例如稀疏矩阵,来提高效率。
  3. 使用多线程:可以将雷区分割成多个子区域,使用多线程并行计算,进一步提高效率。

进一步学习

  1. 尝试使用其他编程语言实现扫雷游戏。
  2. 探索更高级的扫雷游戏算法,例如使用深度优先搜索或广度优先搜索来优化游戏逻辑。
  3. 研究扫雷游戏的 AI 算法,让计算机自动玩扫雷游戏。

希望本文能为读者提供一些启发,帮助读者更好地理解和学习游戏编程。

扫雷游戏:C++ 代码实现及优化

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

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