A *路径寻找算法并不总是找到最短路径C#XNA

时间:2012-12-11 14:49:35

标签: c# xna path-finding a-star

我正在创建一个简单的XNA C#自上而下的游戏。在游戏中,你会看到一个像地图一样的迷宫周围的敌人。 ATM我设置它,以便在游戏开始时敌人找到最短的路径(它确实如此)。如果玩家已移动,则每秒都会找到一条新路径。

游戏总是找到一条通往你的路线,但似乎很难找到到达移动目标的最短路线,有时候在你移动的时候进入一个环路,当你停下来时,敌人在地图的中途行进到找到你,即使你只有几步之遥。它似乎不是启发式的,因为我删除它(使它成为dijkstra),它似乎仍然有同样的问题。我认为这是一件我忽略的简单事情,但我很难搞清楚什么。

提前致谢

 class PathFinder
{
    private Cell[,] map = Game1.cellArray;


    public List<Cell> calculate(int currX, int currY, int destX, int destY)
    {
        resetMap();

        Debug.WriteLine("starting over");
        List<Cell> path = new List<Cell>();
        List<Cell> openList = new List<Cell>();
        List<Cell> closedList = new List<Cell>();

        Cell startPos = map[currY, currX];
        Cell endPos = map[destY, destX];
        startPos.closed = true;
        closedList.Add(startPos);


        Cell curPos = startPos;

        while (!closedList.Contains(endPos))
        {

            //add adjacent nodes to list, discover their scores
            foreach (Cell v in getAdj(curPos))
            {
                if (v.walkable == true && v.closed == false)
                {
                    if (!openList.Contains(v))
                    {
                        v.parent = curPos;
                        v.H = getH(v, endPos);
                        v.G = v.parent.G + 10;

                        v.F = v.G + v.H;
                        openList.Add(v);


                    }
                        //if square already on list would benefit from current tile being parent, make it so
                    else if (curPos.G + 10 < v.G)
                    {
                        v.parent = curPos;
                        v.G = v.parent.G + 10;
                        v.F = v.G + v.H;
                    }
                }
            }
            if (openList.Count <= 1) {/*Console.WriteLine("Returned NULL");*/ return null; }

            curPos = openList[1];

            curPos.closed = true;
            closedList.Add(curPos);
            openList[1] = openList[openList.Count - 1];
            openList.RemoveAt(openList.Count - 1);

            openList.OrderBy(o => o.F);
            openList.Reverse();

        }

        //backtrack to discover path
        Cell curNode = endPos;
        path.Add(endPos);
        while (curNode != startPos)
        {
            curNode = curNode.parent;
            path.Add(curNode);
            Debug.WriteLine("Path// X: " + curNode.xLocation + " Y: " + curNode.yLocation);
        }

        path.Reverse();
        return path;
    }
    //finds heuristic of current square by checking distance to destination ignoring walls 
    private int getH(Cell curPos, Cell endPos)
    {
        int diffX = curPos.xLocation - endPos.xLocation;
        int diffY = curPos.yLocation - endPos.yLocation;

        if (diffX < 0)
        {
            diffX *= -1;
        }
        if (diffY < 0)
        {
            diffY *= -1;
        }
        return ((diffX + diffY) * 10);
    }

    //get list of adjacent Cells
    private List<Cell> getAdj(Cell curPos)
    {
        List<Cell> adjList = new List<Cell>();

       if (curPos.xLocation - 1 >= 0){
            adjList.Add(map[curPos.yLocation, curPos.xLocation - 1]);
        }
        if (curPos.xLocation < 19)
        {
            adjList.Add(map[curPos.yLocation, curPos.xLocation + 1]);
        }
        if (curPos.yLocation - 1 >= 0)
        {
            adjList.Add(map[curPos.yLocation - 1, curPos.xLocation]);
        }
        if (curPos.yLocation < 19)
        {
            adjList.Add(map[curPos.yLocation + 1, curPos.xLocation]);
        }


        return adjList;
    }

    private void resetMap()
    {
        //reset Cells to default values
        for (int r = 0; r < map.GetLength(1); r++)
        {
            for (int c = 0; c < map.GetLength(0); c++)
            {
                map[r, c].reset();
            }
        }
    }
}

1 个答案:

答案 0 :(得分:0)

刚刚解决了这个问题。在更改当前选定的磁贴之前未进行排序。我以为我得分不正确大声笑。

相关问题