我正在为我的大学编程项目写一个小roguelike游戏。我想尝试实现一个简单的寻路机制,这将涉及到用从0开始向上的数字填充平铺Map,数字是到玩家的距离。这将允许怪物找到到玩家的最短路径。这是我想出的算法:
void monster_vision(int player_x, int player_y, int score = 0)
{
if (map[player_x][player_y] == '.')
{
map[player_x][player_y] = score;
}
else
return;
monster_vision(player_x - 1, player_y, score + 1);
monster_vision(player_x + 1, player_y, score + 1);
monster_vision(player_x, player_y - 1, score + 1);
monster_vision(player_x, player_y + 1, score + 1);
}
正如我所说,这只是要素的单文件草稿,Map的类型为std::array<std::array<char, map_size>, map_size
,最初在边缘填充#,内部填充点
我希望Map看起来像这样:例如,如果map的大小设置为5,函数调用为:monster_vision(2,2)
#####
#212#
#101#
#212#
#####
我得到的结果是
#####
#218#
#307#
#456#
#####
根据我的理解,一些递归调用一定会以某种方式重叠,但我认为我放置的保护应该足以防止写入已经得分的单元格。
3条答案
按热度按时间8fq7wneg1#
下面是一个使用
std::deque
实现bfs的实现:它依赖于这些助手:
请注意,您不需要'#'字符形式的边界守卫,因为您知道棋盘的大小。相反,零分用于标记未访问的单元格。不幸的是,这引入了大量的分支条件,可以进一步改进。
Here is a complete demo .
wljmcqd82#
问题是你的算法是递归的。想象一下它实际上是做什么的,它在你的Map中设置值
0
(如果.
),那么它调用monster_vision
作为下一个坐标,但值为1
。现在魔术发生了。你仍然在第二次调用monster_vision
,但是现在它再次调用monster_vision
(深度2)用于下一个位置,但是值2
,等等。因此,对
monster_vision
的四个调用在代码中彼此在下面,它们不是按顺序调用的。这个顺序是迭代的,只有当你在所有四个“方向”上遇到第一个非.
时才会被打破......这正是你所观察到的。迭代算法听起来不错,但不会起作用。
根据你的游戏逻辑,你必须决定你想如何计算距离/得分,eidogg.怪物可以对角线移动吗?
我建议一个简单的纯x/y运动和:
然而,正如在评论中所指出的,在这个特定的情况下和许多其他情况下,预先计算距离可能没有好处。
but5z9lq3#
变化
到
以便在更快访问的情况下而不仅仅是在第一次访问的情况下也设置新的分数。