A*寻路算法入门(七)

大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处.

如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;)


免责申明:本博客提供的所有翻译文章原稿均来自互联网,仅供学习交流之用,请勿进行商业用途。同时,转载时不要移除本申明。如产生任何纠纷,均与本博客所有人、发表该翻译稿之人无任何关系。谢谢合作!

一只没有远见的猫咪

在上面的例子中,我们看到猫咪在选择最短路径的时候,它总是选择最好的方块(在未来最短路径中的一块) — 就像他它是一只有远见的猫咪一样!

但是如果这只猫咪不总是头脑清楚的去选择第一个添加到列表中的方块时会发生什么呢?

这里有一张示意图显示了这些被用在该处理过程中的方块.你将看到猫咪会尝试更多的方块,但是它仍然能找到一条最短的路径(不一定和前面相同,但是等效的):

A*寻路算法入门(七)

上图中红色方块并不表示最短路径,它仅表示在某些点上选择的”S”方块.

我建议你检查上图并且视图跟随遍历它.这次,你将发现无论怎样”最坏的”的路径被选择,在最后你仍然可以得到一条最短的路径!

所以你可以看到跟随”错误”的方块也没有关系,在最终你仍然可以得到最短路径,即使你会经历更多次的迭代.

在我们的实现中,我们将按以下算法将方块添加到开放列表中去:

  • 邻居方块将按以下顺序返回:上/左/下/右.
  • 一个具有相同分值的方块将被添加到开放列表中所有相同分值相同方块的最后面(所以第一个添加的将第一个被猫咪取得).

这里是一张回溯的示意图:

A*寻路算法入门(七)

最短路径通过开始从目的地回退到其父方块来建立起来(比如:在目的地我们可以看到箭头指向右侧,所以该方块的父方块在它的左侧).

最终,我们可以通过下面的伪代码来合成猫咪的处理.它被写为Objective-C,但是你可以用任何语言实现:

[openList add:originalSquare]; // start by adding the original position to the open list
do {
    currentSquare = [openList squareWithLowestFScore]; // Get the square with the lowest F score

    [closedList add:currentSquare]; // add the current square to the closed list
    [openList remove:currentSquare]; // remove it to the open list

    if ([closedList contains:destinationSquare]) { // if we added the destination to the closed list, we've found a path
        // PATH FOUND
        break; // break the loop
    }

    adjacentSquares = [currentSquare walkableAdjacentSquares]; // Retrieve all its walkable adjacent squares

    foreach (aSquare in adjacentSquares) {

        if ([closedList contains:aSquare]) { // if this adjacent square is already in the closed list ignore it
            continue; // Go to the next adjacent square
        }

        if (![openList contains:aSquare]) { // if its not in the open list

            // compute its score, set the parent
            [openList add:aSquare]; // and add it to the open list

        } else { // if its already in the open list

            // test if using the current G score make the aSquare F score lower, if yes update the parent because it means its a better path

        }
    }

} while(![openList isEmpty]); // Continue until there is no more available square in the open list (which means there is no path)

你有没有小激动想要实现一下?!在下一篇课程中,我们将完全实现它!

接下来呢?

恭喜,你现在了解了基本的A*寻路算法!如果你想要从这里学到更多内容,我推荐你阅读 Amit’s A* Pages.

在本系列的下一篇课程中,我们将在一个简单的Cocos2D地图游戏中实现A*算法!(之前猫猪写过的 Cocos2D将v1.0的tileMap游戏转换到v3.4中一例系列博文即是前奏,大家可以先看一下 ;)

与此同时,如果你有关于A*算法的任何问题,请加入下面的讨论中来!

上一篇:App Naver Line 5.3 add new features - "True Delete"


下一篇:TSQL 根据经纬度计算两点间的距离;返回米(m)