c++ - 检查二维向量的特定模式
问题描述
所以我有一个小游戏,它从 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++ 编码。谢谢!
解决方案
一旦围绕地图,您可能会做类似的事情:
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;
推荐阅读
- javascript - Cannot bind vue store to state
- r - latex kable 并排桌“不在外部标准模式”
- sass - 媒体选择器“扩展”引导 SASS 类
- python - 选择优化函数的数组子样本
- javascript - 为什么 JavaScript UpdateExpression 语法如此定义?
- vba - 按日期过滤 - VBA
- raku - Perl 6 的最长标记匹配中的非贪婪模式是什么?
- python - Python Seaborn Boxplot:在晶须上叠加 95 个百分位值
- python - 设计这个轨迹类的最佳方法
- sql - 使用 Rollup 时重命名 Null 值