예제 #1
0
        public void FindPath(MapPosition startPosition, MapPosition endPosition, ref List <MapPosition> results)
        {
            if (results == null)
            {
                results = new List <MapPosition>();
            }
            results.Clear();

            // if(the locations are the same then ... exit this procedure.
            if (object.Equals(startPosition, endPosition))
            {
                return;
            }

            // Add the starting square to the open list.
            NodesCollection openedNodes = new NodesCollection();
            NodesCollection closedNodes = new NodesCollection();

            openedNodes.Add(startPosition);

            MapCellsCollection parentNodes = new MapCellsCollection();
            int                lowestItem, foundItem, nodeIndex, parentIndex;
            NodeItem           currentNode;
            List <MapPosition> connectingNodes = new List <MapPosition>();

            do
            {
                // ... Look for the lowest F cost square on the open list ...
                lowestItem = openedNodes.FindByLowestF();
                if (lowestItem < 0)
                {
                    return;
                }
                currentNode = openedNodes[lowestItem];

                // ... Switch it to the close list ...
                closedNodes.Add(currentNode);
                openedNodes.RemoveAt(lowestItem);

                // ... if(we added the target square to the closed list, then quit.
                if (object.Equals(currentNode.Position, endPosition))
                {
                    break;
                }

                // ... for(each of the cell's sides to this current square ...
                this.EnumConnectingNodes(currentNode.Position, ref connectingNodes);
                if (connectingNodes != null && connectingNodes.Count > 0)
                {
                    for (nodeIndex = 0; nodeIndex < connectingNodes.Count; nodeIndex++)
                    {
                        if (closedNodes.FindIndex(connectingNodes[nodeIndex]) < 0)
                        {
                            // ... Find if the cell is in the open list ...
                            foundItem = openedNodes.FindIndex(connectingNodes[nodeIndex]);
                            // ... if(the cell isn't in the open list then add it ...
                            if (foundItem < 0)
                            {
                                openedNodes.Add(connectingNodes[nodeIndex], (currentNode.G + 1), connectingNodes[nodeIndex].GetDistance(endPosition));

                                parentIndex = parentNodes.FindIndex(connectingNodes[nodeIndex]);
                                if (parentIndex < 0)
                                {
                                    parentNodes.Add(connectingNodes[nodeIndex], currentNode.Position);
                                }
                                else
                                {
                                    parentNodes[parentIndex].Next = currentNode.Position;
                                }
                            }
                            else
                            {
                                if (openedNodes[foundItem].G < currentNode.G)
                                {
                                    openedNodes[foundItem].G = (currentNode.G + 1);

                                    parentIndex = parentNodes.FindIndex(connectingNodes[nodeIndex]);
                                    if (parentIndex < 0)
                                    {
                                        parentNodes.Add(connectingNodes[nodeIndex], currentNode.Position);
                                    }
                                    else
                                    {
                                        parentNodes[parentIndex].Next = currentNode.Position;
                                    }
                                }
                            }
                        }
                    } //nodeIndex
                }
            } while(true);

            // Add the last cell to the list.
            results.Insert(0, (MapPosition)endPosition.Clone());

            // Now that we're done, let's check the results and return it.
            int currentAddress = parentNodes.FindIndex(endPosition);

            do
            {
                if (currentAddress < 0 || (parentNodes[currentAddress].Next == null || parentNodes[currentAddress].Next.IsEmpty()))
                {
                    break;
                }
                else
                {
                    if (!object.Equals(parentNodes[currentAddress].Next, startPosition))
                    {
                        results.Insert(0, (MapPosition)parentNodes[currentAddress].Next.Clone());
                    }
                    currentAddress = parentNodes.FindIndex(parentNodes[currentAddress].Next);
                }
            } while(true);
        } // FindPath