C# A-star路径查找算法:-使用openList中的所有元素关闭列表(导致索引超出范围) oCount=openList中的元素数 cCount=closedList中的元素数

C# A-star路径查找算法:-使用openList中的所有元素关闭列表(导致索引超出范围) oCount=openList中的元素数 cCount=closedList中的元素数,c#,a-star,indexoutofrangeexception,C#,A Star,Indexoutofrangeexception,我正在基于瓷砖的环境中实现无对角线移动的A-star。当oCount=0时,当我尝试使用[oCount-1]访问openList中的最后一个元素时,经常会在openList上抛出一个“索引超出范围错误”。oCount只有在Account为159时才变为0,这表明closedList已经使用了openList中的每个元素。以下是一个例子: Account变为159->oCount为0->检查closedList中磁贴周围的磁贴[158]->无有效磁贴->返回while循环的开头->尝试将openL

我正在基于瓷砖的环境中实现无对角线移动的A-star。当oCount=0时,当我尝试使用[oCount-1]访问openList中的最后一个元素时,经常会在openList上抛出一个“索引超出范围错误”。oCount只有在Account为159时才变为0,这表明closedList已经使用了openList中的每个元素。以下是一个例子:

Account变为159->oCount为0->检查closedList中磁贴周围的磁贴[158]->无有效磁贴->返回while循环的开头->尝试将openList中的最后一个元素移动到closedList错误

以下是我的FindPath方法: 磁贴的栅格位置基于其在阵列中的位置,即磁贴[0,0]是左上角的磁贴


您得到的实际异常是什么?堆栈跟踪是什么?你试过调试吗?@user3444160我得到一个ArgumentOutOfRangeException。我基本上是在尝试访问openList[-1]。请原谅,我对编程非常陌生,所以我不熟悉堆栈跟踪。我从星期天就开始调试了。我已经把可能性缩小到我现在所拥有的范围,但我不确定我能做得更进一步,尽管我能做的可能是堆栈跟踪?。我更愿意理解如何解决我的问题,但我知道这里的答案直接基于提供的问题。[编辑:问题中添加了堆栈跟踪信息。请告诉我是否可以]查看Eric Lippert对C中简单a-star实现的精彩描述:。由于对OpenSet和ClosedSet使用了不适当的数据结构,所以您的实现在任何非平凡的图形上都不起作用。如果您感兴趣,我在过去也实现过类似的问题。我去看看。仍然想知道我的closedList是如何使用所有openList元素的。我想对我来说,了解我在这里的错误是很重要的
//xBound + yBound = the bounding area with which the character can walk
public List<int> FindPath(Tile[,] tile, Vector2 xBoundary, Vector2 yBoundary, Vector2 startTile, Vector2 endTile)
    {
        //Initialize variables
        List<Tile> openList = new List<Tile>();
        List<Tile> closedList = new List<Tile>();
        List<int> path = new List<int>();
        int cCount = 0;  
        int oCount = 0;

        tile[(int)startTile.X, (int)startTile.Y].PDir = 0; //PDir = direction to its parent tile

        //Add starting tile to openList
        openList.Add(tile[(int)startTile.X, (int)startTile.Y]);

        //Set scores for starting tile
        openList[0].G = 0;
        openList[0].H = (int)Math.Abs(endTile.X - startTile.X) + (int)Math.Abs(endTile.Y - startTile.Y);
        openList[0].F = openList[0].G + openList[0].H;


        while (path.Count == 0)
        {
            oCount = openList.Count;

            //Sort openList by decreasing F score
            openList = Sort(openList);

            //Move tile with lowest F score from openList to closedList
            closedList.Add(openList[oCount - 1]); //ERROR OCCURS HERE
            openList.RemoveAt(oCount - 1);
            cCount = closedList.Count;


            //Add valid surrounding tiles OR Alter valid existing tiles
            //----------------------------------------------------------------------------------------------
            for (int a = -1; a < 2; a += 2) //[a = difference in grid x-position]
            {
                //If tile is walkable, not in closed list, and within set boundaries...
                if (tile[closedList[cCount - 1].X + a, closedList[cCount - 1].Y].Collision == false
                    && !closedList.Contains(tile[closedList[cCount - 1].X + a, closedList[cCount - 1].Y])
                    && closedList[cCount - 1].X + a >= xBoundary.X && closedList[cCount - 1].X + a <= xBoundary.Y       //Test if boundaries must be < or <=
                    && closedList[cCount - 1].Y >= yBoundary.X && closedList[cCount - 1].Y <= yBoundary.Y)
                {
                    //If tile not in open list...
                    if (!openList.Contains(tile[closedList[cCount - 1].X + a, closedList[cCount - 1].Y]))
                    {
                        //Add tile
                        openList.Add(tile[closedList[cCount - 1].X + a, closedList[cCount - 1].Y]);
                        oCount = openList.Count;

                        //Set parent direction
                        if (a == -1)
                            tile[closedList[cCount - 1].X + a, closedList[cCount - 1].Y].PDir = 1;
                        else if (a == 1)
                            tile[closedList[cCount - 1].X + a, closedList[cCount - 1].Y].PDir = 3;

                        //Calculate F, G and H
                        openList[oCount - 1].G = closedList[cCount - 1].G + 1;
                        openList[oCount - 1].H = (int)Math.Abs(endTile.X - openList[oCount - 1].X) + (int)Math.Abs(endTile.Y - openList[oCount - 1].Y);
                        openList[oCount - 1].F = openList[oCount - 1].G + openList[oCount - 1].H;

                    }
                    //otherwise, check if current path is better than the previous path that tile had...
                    else if (closedList[cCount - 1].G + 1 < tile[closedList[cCount - 1].X + a, closedList[cCount - 1].Y].G)
                    {
                        //Set new parent direction
                        if (a == -1)
                            tile[closedList[cCount - 1].X + a, closedList[cCount - 1].Y].PDir = 1;
                        else if (a == 1)
                            tile[closedList[cCount - 1].X + a, closedList[cCount - 1].Y].PDir = 3;

                        //Re-calculate G and H values
                        int g = closedList[cCount - 1].G + 1;
                        int h = (int)Math.Abs(endTile.X - tile[closedList[cCount - 1].X + a, closedList[cCount - 1].Y].X) + (int)Math.Abs(endTile.Y - tile[closedList[cCount - 1].X + a, closedList[cCount - 1].Y].Y);

                        //Set values to tile
                        tile[closedList[cCount - 1].X + a, closedList[cCount - 1].Y].G = g;
                        tile[closedList[cCount - 1].X + a, closedList[cCount - 1].Y].H = h;
                        tile[closedList[cCount - 1].X + a, closedList[cCount - 1].Y].F = g + h;     //including f-value...
                    }
                }
            }

            // Above for-loop repeated for [b = difference in y-position]

            //----------------------------------------------------------------------------------------------

            //If at endTile...
            if (closedList[cCount - 1].Y == endTile.Y && closedList[cCount - 1].X == endTile.X)
            {
                path = PlotPath(tile, tile[(int)startTile.X, (int)startTile.Y], tile[(int)endTile.X, (int)endTile.Y]);
            }
        }

        return path;
    }
Mini RPG (test1).exe!Mini_RPG__test1_.AI.FindPath(Mini_RPG__test1_.Tile[,] tile, Microsoft.Xna.Framework.Vector2 xBoundary, Microsoft.Xna.Framework.Vector2 yBoundary, Microsoft.Xna.Framework.Vector2 startTile, Microsoft.Xna.Framework.Vector2 endTile) Line 45  C#

Mini RPG (test1).exe!Mini_RPG__test1_.Character1.UpdateDecisions(Mini_RPG__test1_.Tile[,] tileArray) Line 106 + 0xa9 bytes  C#

Mini RPG (test1).exe!Mini_RPG__test1_.Character1.Update(Microsoft.Xna.Framework.GameTime gameTime, Mini_RPG__test1_.Tile[,] tileArray) Line 69 + 0xb bytes  C#

Mini RPG (test1).exe!Mini_RPG__test1_.Game1.Update(Microsoft.Xna.Framework.GameTime gameTime) Line 745 + 0x28 bytes C#

[External Code] 
Mini RPG (test1).exe!Mini_RPG__test1_.Program.Main(string[] args) Line 15 + 0xb bytes   C#