예제 #1
0
        public void SetRoute(RouteResult route)
        {
            //  if we're instructed to move to this tile, we're here!
            if (route.nodes.Count <= 0)
            {
                return;
            }

            startMoveTime    = Time.deltaTime;
            currentNodeIndex = 0;

            //  assume we're on the starting Node
            currentNode = route.nodes[0];
            targetNode  = route.nodes[1];
        }
예제 #2
0
        /// <summary>
        /// Given a starting and ending node, determine the
        /// shortest path between the two
        /// </summary>
        /// <param name="start">The starting node</param>
        /// <param name="end">The ending node</param>
        /// <returns>A RouteResult</returns>
        public RouteResult Route(Node start, Node end, bool diagonal = true)
        {
            //  create the result object
            RouteResult result = new RouteResult();

            //  create the path for the starting node
            Path startPath = new Path {
                cheapestPathCost = 0
            };

            startPath.nodes.Add(start);

            //  add that path to the dict
            paths.Add(start.GetInstanceID(), startPath);

            //  create a stack of nodes and queue the starting node
            Stack nodes = new Stack();

            nodes.Push(start);

            //  while we have nodes...
            while (nodes.Count > 0)
            {
                Node current = nodes.Pop() as Node;

                //  retrieve the path for this node if exists in the dictionary
                pathForKey(current.GetInstanceID(), out Path currentPath);

                //  mark this node as visited in the path
                currentPath.visited = true;

                //  list of nodes to sort and prioritize next
                List <Node> nextNodes = new List <Node>();

                //  for each one fo the nodes neighbors, supporting
                //  both diagonal and direct:
                List <Node> neighbors = current.directNeighbors;
                if (diagonal)
                {
                    neighbors = current.neighbors;
                }
                foreach (Node neighborNode in neighbors)
                {
                    //  in the event that a neighbor node gets
                    //  removed while pathing or a neighbor is occupied
                    if (neighborNode == null || neighborNode.Occupied)
                    {
                        continue;
                    }

                    //  create a new path for this neighbor
                    pathForKey(neighborNode.GetInstanceID(), out Path neighborPath);

                    //  determine the cost to get to this node
                    int cost = currentPath.cheapestPathCost + neighborNode.cost;

                    //  if the calculated cost is less than the current n.cost (defaults to int.max),
                    //  update this as the shortest path to this node
                    if (cost < neighborPath.cheapestPathCost)
                    {
                        neighborPath.cheapestPathCost = cost;
                        neighborPath.nodes.Clear();

                        //  add all nodes in current path to this neighbors nodes
                        foreach (Node shortestNode in currentPath.nodes)
                        {
                            neighborPath.nodes.Add(shortestNode);
                        }

                        //  now add this node as well
                        neighborPath.nodes.Add(neighborNode);
                    }

                    //  if this node isn't visited, add it to
                    //  nextNodes to be sorted and processed
                    if (!neighborPath.visited)
                    {
                        nextNodes.Add(neighborNode);
                    }
                }

                //  sort all neighbor nodes that haven't been processed
                //  by their distance to the end node and add them to
                //  the stack
                nextNodes = prioritizeNodes(nextNodes, start, end);
                foreach (Node nextNode in nextNodes)
                {
                    nodes.Push(nextNode);
                }

                //  if this is the end node, set the result and return
                if (current == end)
                {
                    result.cost  = currentPath.cheapestPathCost;
                    result.nodes = currentPath.nodes;
                    return(result);
                }
            }

            //  if no return, return empty result...
            return(result);
        }