使用深度限制搜索进行路径搜索(Unity / C#〜)

时间:2014-07-17 14:49:21

标签: c# unity3d depth-first-search

我正在制作一个基于网格的游戏,角色可以轮流移动他们的单位。每个角色都有一个移动量(例如4 - 他们可以移动4个牌)。 我已经实施了DLS(仅限于他们的移动金额)。使用此功能,可以突出显示玩家可以移动到的所有可用图块。

这很好用。但是,我想修改算法(或实现一个特定的算法)来计算出路线。例如,玩家想要G3 - 角色应该采取什么路线(前进1,左1等)。 请记住,每个磁贴都可以具有不同的属性(例如某些磁贴可能被阻止)。

代码

private void DLS(int x, int z, int depth, float jump, float previousHeight)
    {
        int resistance=1;
        if (depth >=0)
        {
            tiles[x,z].GetComponentInChildren<CheckIfClicked>().Selected();
            if (x+1 < 25)
            {
                CheckTile(x+1, z, depth, jump, previousHeight);
            }
            if (x-1 >= 0)
            {
                CheckTile(x-1, z, depth, jump, previousHeight);
            }
            if (z+1 <25) 
            {
                CheckTile(x, z+1, depth, jump, previousHeight);         
            }
            if (z-1 >=0)  
            {
                CheckTile(x, z-1, depth,jump, previousHeight);          
            }
        }
    }

    private void CheckTile(int x, int z, int depth, float jump, float previousHeight)
    {   
        float tileHeight = tiles[x, z].GetComponent<TileDimensions>().height;
        float difference = tileHeight - previousHeight;
        if (difference<0) difference*=-1;
        if (!tiles[x, z].GetComponentInChildren<CheckIfClicked>().occupied && difference<jump)
        {
            int resistance = tiles[x, z].GetComponent<TileDimensions>().getResistance();
            if (resistance<0) resistance=1;
            DLS(x, z, depth-resistance, jump, tileHeight);  
        }
    }

我的代码利用了不同的图块属性(例如图块阻力(某些图块限制了移动)和高度(你只能攀爬到目前为止)。)

2 个答案:

答案 0 :(得分:0)

由于您的算法正在运行,我想提供一些增强代码的建议,两者都涉及使用列表/字典。

执行一次路径搜索

如果您可以突出显示每个可移动的图块,这意味着您可以将源自源图块的路径遍历到不同的目标图块,这意味着您将逐个验证图块,直到角色无法进行其他移动。因此,您可以将结果存储到&#34;目标图块 - 列表&#34;的字典中。对。每当您需要检索转到特定磁贴的路径时,只需获取以前存储的路径。

执行路径搜索两次

由于上述方法可能占用大量内存,因此当玩家移动时,您可以再次运行路径搜索算法。第二次执行所花费的时间应该小于第一次执行,因为玩家已经指定某个区块作为路径的目的地。在第二次搜索期间,在递归执行路径搜索功能的同时继续更新列表/字典。将每个有效的中间磁贴保存到列表/字典中,然后在搜索后获取路径。


如果您正在移动平台上开发游戏,即使一点点内存使用也很重要。然后我会建议两次执行路径搜索,只要搜索所花费的时间是玩家可以接受的。

当然,通过Unity Profiler监控性能始终是一个很好的做法,以更好的方式检查哪种方法适合您的需求。

答案 1 :(得分:0)

如果您希望使用更有效的算法,则有两种建议的实现:

1)明星。当您知道要前往的目的地时,最好使用星星,但您需要找到到达目的地的方式。例如,如果你点击了瓷砖G3,并且在G1中,你知道你需要去哪里。一个明星利用启发式试图“猜测”你还需要走多远。这意味着在搜索潜在路线时,A星将尝试在尝试查看其他路线之前采取应该是最短路线。这里有一个很棒的教程:http://www.policyalmanac.org/games/aStarTutorial.htm

2)Djikstra的算法。当您不知道自己要去哪里但想要找到包含某个“事物”的最近节点时,可以更好地使用它,即您可能希望A.I在FPS中搜索最近的健康包。我之前没有实现过Djikstra的算法,但是网上有很多教程。

两者都可以在某些瓷砖和其他任何瓷砖上添加阻力等属性。