/*
         * public functions
         */
        /// <summary>
        /// A*, modified to find a nearest path in case of failure
        /// </summary>
        /// <param name="map">The Map</param>
        /// <param name="startNode">The starting Node</param>
        /// <param name="endNode">The ending Node</param>
        /// <returns>The path as a list of waypoints</returns>
        public static List<Node> findPath(NodeMap map, Node startNode, Node endNode)
        {
            // initialize data
            PQueue open = new PQueue();
            open.enqueue(startNode);
            List<Node> adjacentNodes = new List<Node>();

            // good ol' A*
            while (open.Count > 0)
            {
                // find the open Node with the lowest Fscore and remove it from the open PQueue
                Node current = open.dequeue();

                // if this is our destination Node, we're done; otherwise, close it so we don't travel to it again
                if (current == endNode)
                    return reconstruct(endNode);
                current.close();

                // find every valid Node adjacent to the current Node
                adjacentNodes = map.getAdjacentNodes(current);

                // iterate over all of them
                for (int i = 0; i < adjacentNodes.Count; i++)
                {
                    // grab an adjacent Node and calculate a new GScore and HScore for it
                    Node adjacent = adjacentNodes[i];
                    int tempGScore = current.Gscore + map.pathDistance(current, adjacent);
                    int tempHScore = map.pathDistance(adjacent, endNode);

                    // if we have not opened this Cell, give it new stats and open it
                    if (!adjacent.isOpen)
                    {
                        setAdjacentStats(adjacent, current, tempGScore, tempHScore);
                        open.enqueue(adjacent);
                    }

                    // otherwise, if we have opened it but the new path to it is shorter than the old one, give it new stats and reset its position in the open PQueue
                    else if (tempGScore < adjacent.Gscore)
                    {
                        setAdjacentStats(adjacent, current, tempGScore, tempHScore);
                        //open.resetPosition(adjacent);
                    }
                }
            }

            // no valid path exists, so find the nearest path
            List<Node> closed = createClosed(map);
            Node nearestNode = closed[0];

            // find the closed Node with the lowest Hscore (distance from the intended end); return a path to that Node
            if (closed.Count > 0)
            {
                for (int i = 1; i < closed.Count; i++)
                {
                    if (closed[i].Hscore < nearestNode.Hscore)
                        nearestNode = closed[i];
                }
            }
            return reconstruct(nearestNode);
        }
        /*
         * public functions
         */
        /// <summary>
        /// A*, modified to find a nearest path in case of failure
        /// </summary>
        /// <param name="map">The Map</param>
        /// <param name="startCell">The starting Cell</param>
        /// <param name="endCell">The ending Cell</param>
        /// <returns>The path as a list of waypoints</returns>
        public static List<Cell> findPath(Map map, Cell startCell, Cell endCell)
        {
            /*
             * Terminology
             *		Gscore			cumulative calculated distance from the start Cell to the given Cell
             *		Hscore			estimated distance from the given Cell to the end Cell.
             *							Overestimating this can result in the calculation of an incorrect (inefficient) path,
             *							but the more it is underestimated, the longer correct path calculation will take
             *		Fscore			Gscore + Hscore; estimated total distance from start to end on a path through the given Cell.
             *							Priority queues (PQueues) are ordered by ascending Fscore, so shortest estimated paths are examined first
             *		open list		A PQueue of Cells to be examined.  Initially contains the start Cell
             *		closed list		A List<Cell> of Cells that have been examined
             *		adjacent list	A PQueue of Cells adjacent to the current Cell
             */

            // initialize the lists
            PQueue open = new PQueue();
            open.enqueue(startCell);
            List<Cell> closed = new List<Cell>();
            PQueue adjacentCells = new PQueue();
            iterations = 0;

            // good ol' A*
            while (open.count() > 0)											    // iterate until we have examined every appropriate Cell
            {
                //open.print("Open", true);
                Cell currentCell = open.dequeue();								    // look at the Cell with the lowest Fscore and remove it from the open list
                if (currentCell == endCell)										    // if this is our destination Cell, we're done!
                    return reconstruct(endCell);									    // so return the path
                closed.Add(currentCell);										    // otherwise, close this Cell so we don't travel to it again
                adjacentCells = getAdjacentCells(map, open, closed, currentCell);	// now find every valid Cell adjacent to the current Cell
                //adjacentCells.print("Adjacent", false);
                while (adjacentCells.count() != 0)                                  // iterate over all of them, from lowest to highest Fscore
                {
                    Cell adjacentCell = adjacentCells.dequeue();									// grab the current adjacent Cell
                    int tempGScore = currentCell.Gscore + pathDistance(currentCell, adjacentCell);	// calculate a temporary Gscore as if we were traveling to this Cell from the current Cell
                    if (!open.contains(adjacentCell) || tempGScore < adjacentCell.Gscore)			// if this Cell has not been added to the open list, or if tempGscore is less than the Cell's current Gscore
                    {
                        int h = pathDistance(adjacentCell, endCell);									// estimate the Cell's Hscore
                        adjacentCell.prev = currentCell;												// set the Cell's prev pointer to the current Cell
                        adjacentCell.Hscore = h;														// set the Cell's Hscore
                        adjacentCell.Gscore = tempGScore;												// set the Cell's Gscore
                        adjacentCell.Fscore = tempGScore + h;											// set the Cell's Fscore
                    }
                    if (!open.contains(adjacentCell))												// if the adjacent Cell we just examined is not yet on the open list, add it
                        open.enqueue(adjacentCell);
                }
                iterations++;
            }

            // no valid path exists, so find the nearest path
            closed.RemoveAt(0);										// remove the start Cell from the closed List
            if (closed.Count > 0)									// if there are still Cells on the closed list
            {
                Cell nearestCell = closed[0];							// find the closed Cell with the lowest Hscore;
                for (int i = 1; i < closed.Count; i++)					// this should be the Cell closest to the desired destination,
                {														// so return a path ending with that Cell.
                    if (closed[i].Hscore < nearestCell.Hscore)
                        nearestCell = closed[i];
                }
                return reconstruct(nearestCell);
            }
            else
            {
                List<Cell> path = new List<Cell>();					// otherwise, our only path was the start Cell (i.e. we are completely trapped);
                path.Add(endCell);									// so return a path with just that Cell.
                return path;
            }
        }
        /*
         * public functions
         */

        /// <summary>
        /// A*, modified to find a nearest path in case of failure
        /// </summary>
        /// <param name="map">The Map</param>
        /// <param name="startNode">The starting Node</param>
        /// <param name="endNode">The ending Node</param>
        /// <returns>The path as a list of waypoints</returns>
        public static List <Node> findPath(NodeMap map, Node startNode, Node endNode)
        {
            // initialize data
            PQueue open = new PQueue();

            open.enqueue(startNode);
            List <Node> adjacentNodes = new List <Node>();

            // good ol' A*
            while (open.Count > 0)
            {
                // find the open Node with the lowest Fscore and remove it from the open PQueue
                Node current = open.dequeue();

                // if this is our destination Node, we're done; otherwise, close it so we don't travel to it again
                if (current == endNode)
                {
                    return(reconstruct(endNode));
                }
                current.close();

                // find every valid Node adjacent to the current Node
                adjacentNodes = map.getAdjacentNodes(current);

                // iterate over all of them
                for (int i = 0; i < adjacentNodes.Count; i++)
                {
                    // grab an adjacent Node and calculate a new GScore and HScore for it
                    Node adjacent   = adjacentNodes[i];
                    int  tempGScore = current.Gscore + map.pathDistance(current, adjacent);
                    int  tempHScore = map.pathDistance(adjacent, endNode);

                    // if we have not opened this Cell, give it new stats and open it
                    if (!adjacent.isOpen)
                    {
                        setAdjacentStats(adjacent, current, tempGScore, tempHScore);
                        open.enqueue(adjacent);
                    }

                    // otherwise, if we have opened it but the new path to it is shorter than the old one, give it new stats and reset its position in the open PQueue
                    else if (tempGScore < adjacent.Gscore)
                    {
                        setAdjacentStats(adjacent, current, tempGScore, tempHScore);
                        //open.resetPosition(adjacent);
                    }
                }
            }

            // no valid path exists, so find the nearest path
            List <Node> closed      = createClosed(map);
            Node        nearestNode = closed[0];

            // find the closed Node with the lowest Hscore (distance from the intended end); return a path to that Node
            if (closed.Count > 0)
            {
                for (int i = 1; i < closed.Count; i++)
                {
                    if (closed[i].Hscore < nearestNode.Hscore)
                    {
                        nearestNode = closed[i];
                    }
                }
            }
            return(reconstruct(nearestNode));
        }
Beispiel #4
0
        /*
         * public functions
         */

        /// <summary>
        /// A*, modified to find a nearest path in case of failure
        /// </summary>
        /// <param name="map">The Map</param>
        /// <param name="startCell">The starting Cell</param>
        /// <param name="endCell">The ending Cell</param>
        /// <returns>The path as a list of waypoints</returns>
        public static List <Cell> findPath(Map map, Cell startCell, Cell endCell)
        {
            /*
             * Terminology
             *		Gscore			cumulative calculated distance from the start Cell to the given Cell
             *		Hscore			estimated distance from the given Cell to the end Cell.
             *							Overestimating this can result in the calculation of an incorrect (inefficient) path,
             *							but the more it is underestimated, the longer correct path calculation will take
             *		Fscore			Gscore + Hscore; estimated total distance from start to end on a path through the given Cell.
             *							Priority queues (PQueues) are ordered by ascending Fscore, so shortest estimated paths are examined first
             *		open list		A PQueue of Cells to be examined.  Initially contains the start Cell
             *		closed list		A List<Cell> of Cells that have been examined
             *		adjacent list	A PQueue of Cells adjacent to the current Cell
             */

            // initialize the lists
            PQueue open = new PQueue();

            open.enqueue(startCell);
            List <Cell> closed        = new List <Cell>();
            PQueue      adjacentCells = new PQueue();

            iterations = 0;

            // good ol' A*
            while (open.count() > 0)                                                                                                        // iterate until we have examined every appropriate Cell
            {
                //open.print("Open", true);
                Cell currentCell = open.dequeue();                                                    // look at the Cell with the lowest Fscore and remove it from the open list
                if (currentCell == endCell)                                                           // if this is our destination Cell, we're done!
                {
                    return(reconstruct(endCell));                                                     // so return the path
                }
                closed.Add(currentCell);                                                              // otherwise, close this Cell so we don't travel to it again
                adjacentCells = getAdjacentCells(map, open, closed, currentCell);                     // now find every valid Cell adjacent to the current Cell
                //adjacentCells.print("Adjacent", false);
                while (adjacentCells.count() != 0)                                                    // iterate over all of them, from lowest to highest Fscore
                {
                    Cell adjacentCell = adjacentCells.dequeue();                                      // grab the current adjacent Cell
                    int  tempGScore   = currentCell.Gscore + pathDistance(currentCell, adjacentCell); // calculate a temporary Gscore as if we were traveling to this Cell from the current Cell
                    if (!open.contains(adjacentCell) || tempGScore < adjacentCell.Gscore)             // if this Cell has not been added to the open list, or if tempGscore is less than the Cell's current Gscore
                    {
                        int h = pathDistance(adjacentCell, endCell);                                  // estimate the Cell's Hscore
                        adjacentCell.prev   = currentCell;                                            // set the Cell's prev pointer to the current Cell
                        adjacentCell.Hscore = h;                                                      // set the Cell's Hscore
                        adjacentCell.Gscore = tempGScore;                                             // set the Cell's Gscore
                        adjacentCell.Fscore = tempGScore + h;                                         // set the Cell's Fscore
                    }
                    if (!open.contains(adjacentCell))                                                 // if the adjacent Cell we just examined is not yet on the open list, add it
                    {
                        open.enqueue(adjacentCell);
                    }
                }
                iterations++;
            }

            // no valid path exists, so find the nearest path
            closed.RemoveAt(0);                                                                         // remove the start Cell from the closed List
            if (closed.Count > 0)                                                                       // if there are still Cells on the closed list
            {
                Cell nearestCell = closed[0];                                                           // find the closed Cell with the lowest Hscore;
                for (int i = 1; i < closed.Count; i++)                                                  // this should be the Cell closest to the desired destination,
                {                                                                                       // so return a path ending with that Cell.
                    if (closed[i].Hscore < nearestCell.Hscore)
                    {
                        nearestCell = closed[i];
                    }
                }
                return(reconstruct(nearestCell));
            }
            else
            {
                List <Cell> path = new List <Cell>();                                                   // otherwise, our only path was the start Cell (i.e. we are completely trapped);
                path.Add(endCell);                                                                      // so return a path with just that Cell.
                return(path);
            }
        }