首页 > 解决方案 > 检查二维向量的特定模式

问题描述

所以我有一个小游戏,它从 config_file 读取并将信息存储在 Game 类的对象中。到目前为止,这工作正常。我唯一的问题是 config_file 的验证。例如:

G...grass
T...townhall

MAP:
GGGGGGGGGG
GGGGGGGGGG
GGGGGTGGGG
GGGGGGGGGG
GGGGGGGGGG

在'MAP:'行之后,我需要将每个字符存储到一个名为 map 的二维向量中。这工作正常。现在我需要验证地图:可以有一个或多个市政厅,最小尺寸为 1x1,最大尺寸为 3x3。市政厅不能并排放置。

valid:
MAP:
GGGGGGTGGG
GGTTTGGGGT
GGTTTGGGGT
GGTTTGGGGT
GGGGGGTTGG

not valid:
MAP:
GGGGGGGGGG
GGTTTTGGGT
GGTTTGGGGT
GGTTTGGGTT
GGGGTTGGGG

我已经坐在我的电脑前几个小时试图弄清楚这一点。有没有一种无需编写数百个 if 语句即可对其进行编码的简单方法?我正在用 C++ 编码。谢谢!

标签: c++validationdictionaryvector

解决方案


一旦围绕地图,您可能会做类似的事情:

std::size_t compute_width_of_town(const std::vector<std::string>& map,
                                  std::size_t x, std::size_t y)
{
    std::size_t width;
    for (width = 0; map[x + width][y] == 'T'; ++width) {/* Empty */}
    return width;
}

std::size_t compute_height_of_town(const std::vector<std::string>& map,
                                   std::size_t x, std::size_t y)
{
    std::size_t height;
    for (height = 0; map[x][y + height] == 'T'; ++height) {/* Empty */}
    return height;
}

bool validate_inside_town(const std::vector<std::string>& map,
                          std::size_t x, std::size_t y,
                          std::size_t width, std::size_t height)
{
    for (std::size_t i = 0; i != width; ++i) {
        for (std::size_t j = 0; j != height; ++j) {
            if (map[x + i][y + j] != 'T') {
                return false;   
            }
        }
    }
    return true;
}

bool validate_around_town(const std::vector<std::string>& map,
                          std::size_t x, std::size_t y,
                          std::size_t width, std::size_t height)
{
    for (std::size_t i = 0; i != width; ++i) {
        if (map[x + i][y - 1] == 'T'
            || map[x + i][y + height] == 'T') {
            return false;    
        }
    }
    for (std::size_t j = 0; j != height; ++j) {
        if (map[x - 1][y + j] == 'T'
            || map[x + width][y + j] == 'T') {
            return false;    
        }
    }
    return true;
}

bool validate_town(const std::vector<std::string>& map,
                   std::size_t x, std::size_t y)
{
    const std::size_t width = compute_width_of_town(map, x, y);
    const std::size_t height = compute_height_of_town(map, x, y);

    return width <= 3
        && height <= 3
        && validate_inside_town(map, x, y, width, height)
        && validate_around_town(map, x, y, width, height);
}

bool validate_map(const std::vector<std::string>& map)
{
    for (std::size_t i = 1; i != map.size() - 1; ++i) {
        for (std::size_t j = 1; j != map[i].size() - 1; ++j) {
            if (map[i][j] == 'T'
                && map[i - 1][j] != 'T'
                && map[i][j - 1] != 'T'
                && !validate_town(map, i, j))
            {
                return false;   
            }
        }
    }
    return true;
}

并用类似的东西测试它:

std::cout << validate_map({
    "XXXXXXXXXXXX",
    "XGGGGGGTGGGX",
    "XGGTTTGGGGTX",
    "XGGTTTGGGGTX",
    "XGGTTTGGGGTX",
    "XGGGGGGTTGGX",
    "XXXXXXXXXXXX"
    }) << std::endl;

演示


推荐阅读