Проверка 2-мерного вектора для определенных образцов - PullRequest
0 голосов
/ 10 мая 2018

Итак, у меня есть небольшая игра, которая читает файл config_file и сохраняет информацию в объекте Game-класса. Это работает отлично до сих пор. Моя единственная проблема - проверка файла config_file. Например:

G...grass
T...townhall

MAP:
GGGGGGGGGG
GGGGGGGGGG
GGGGGTGGGG
GGGGGGGGGG
GGGGGGGGGG

После строки «MAP:» мне нужно сохранить каждый символ в двухмерном векторе, называемом картой. Это отлично работает. Теперь мне нужно проверить карту: Может быть одна или несколько ратуш с минимальным размером 1x1 и максимальным размером 3x3. Ратуши нельзя размещать рядом друг с другом.

valid:
MAP:
GGGGGGTGGG
GGTTTGGGGT
GGTTTGGGGT
GGTTTGGGGT
GGGGGGTTGG

not valid:
MAP:
GGGGGGGGGG
GGTTTTGGGT
GGTTTGGGGT
GGTTTGGGTT
GGGGTTGGGG

Я часами сидел перед компьютером, пытаясь понять это. Есть ли простой способ его кодирования без написания сотен операторов if? Я кодирую в C ++. Спасибо!

1 Ответ

0 голосов
/ 10 мая 2018

Вы можете сделать что-то подобное, когда окружите карту:

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;

Демо

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...