我正在做2D数组映射,例如:

* 0 1 2 3 4 5 6
0 # # # # # P #
1 # # # # # # #
2 # # # # # # #
3 # # T # # # #
4 # # # # # # #

这是一个游戏。 “T”是巨魔,“P”是玩家。巨魔在该游戏中追逐玩家。假设玩家现在不会移动。
Troll的位置(行,列)为(3,2)和Player(0,5)

巨魔可以通过向右上方走来追逐玩家。也就是说,只需3个步骤即可到达P位置:
(3,2)->(2,3)->(1,4)->(0,5)

但是,当我使用欧几里德距离公式时:
    (int) Math.floor(Math.sqrt(Math.pow((0-3) , 2) + Math.pow((5-2) , 2))) ;

到那里需要4个步骤。

我对距离公式感到困惑。在这种情况下我不能使用它吗?但是在某些情况下,它会采取正确的步骤。

希望有人可以解释这个问题,谢谢。

最佳答案

我认为您是指能够沿对角线移动。如果您沿对角线移动,则实际上可以移动sqrt(2)“单位”,因此您将能够“更快地移动”,因为在使用对角线时,每步需要占用多个单位。

当巨魔和玩家以相同的x或y值对齐时,在某些情况下它会为您工作,因此您只需要移动一个单位即可到达他。

如果您想避免对角线,那么就不能采取“更快”的移动,一个好的距离度量是manhattan distance,基本上是

manhattan_distance(a,b) = abs(a.x - b.x) + abs(a.y - b.y)

添加:如果要保持启用对角线,可以将距离计算为:
diffX = abs(a.x - b.x)
diffY = abs(a.y - b.y)
numSteps = max(diffX, dixxY) //max is returning the higher value of both.

之所以有效,是因为您将要进行尽可能多的对角线移动,并且这个数字是min(diffX,diffY),然后您只需在一个轴上移动以提醒移动,通过min(diffX,diffY)步骤您可以在该轴上“更近”,因此,您需要进行max(diffX-diffY) - min(diffX,diffY)移动,现在将两个“种类”的移动(对角/非对角线)移动相加,您将得到:
numMoves = max(diffX-diffY) - min(diffX,diffY) + min(diffX,diffY) = max(diffX-diffY)

例如,在您的矩阵上:
diffX = abs(3-0) = 3
diffY = abs(2-5) = 3
max(diffX,diffY) = 3

tl;博士:
  • 经典欧几里得距离不起作用,因为对角线位于
    长度sqrt(2)-使用时移动速度更快。
  • 可以通过避免对角线和使用曼哈顿来解决
    距离dist(a,b) = abs(a.x - b.x) + abs(a.y - b.y)
  • 或通过允许对角线并使用距离度量:dist(a,b) = max{abs(a.x-b.x),(a.y-b.y)}
  • 07-26 09:20