public bool Search(out GlobalPath solution, bool returnPartialSolution = false)
        {
            solution = null;
            NodeRecord bestNode = null;

            for (int max = 0; max < this.NodesPerFrame; max++)
            {
                if (Open.CountOpen() == 0)
                {
                    this.InProgress = false;
                    break;
                }
                bestNode = Open.GetBestAndRemove();
                this.TotalExploredNodes++;
                if (bestNode.node == this.GoalNode)
                {
                    solution        = CalculateSolution(bestNode, returnPartialSolution);
                    this.InProgress = false;
                    return(true);
                }
                Closed.AddToClosed(bestNode);
                var outConnections = bestNode.node.OutEdgeCount;
                //Debug.Log(bestNode.hValue);
                for (int i = 0; i < outConnections; i++)
                {
                    this.ProcessChildNode(bestNode, bestNode.node.EdgeOut(i), i);
                }
            }
            this.TotalProcessingTime += Time.deltaTime;
            //solution = CalculateSolution(bestNode, true);
            return(true);
        }
        protected virtual void ProcessChildNode(NodeRecord parentNode, NavigationGraphEdge connectionEdge, int edgeIndex)
        {
            //this is where you process a child node
            var        childNode  = GenerateChildNodeRecord(parentNode, connectionEdge);
            NodeRecord childOpen  = Open.SearchInOpen(childNode);
            NodeRecord childClose = Closed.SearchInClosed(childNode);

            if (childOpen == null && childClose == null)
            {
                Open.AddToOpen(childNode);
                if (this.MaxOpenNodes < Open.CountOpen())
                {
                    this.MaxOpenNodes = Open.CountOpen();
                }
                // childOpen.status = NodeStatus.Open;
            }

            else if (childOpen != null && childOpen.fValue > childNode.fValue)
            {
                Open.Replace(childOpen, childNode);
            }

            else if (childClose != null && childClose.fValue > childNode.fValue)
            {
                Closed.RemoveFromClosed(childClose);
                Open.AddToOpen(childNode);
                //childOpen.status = NodeStatus.Open;
            }
        }
示例#3
0
        protected override void ProcessChildNode(NodeRecord bestNode, NavigationGraphEdge connectionEdge, int edgeIndex)
        {
            float f;
            float g;
            float h;

            var childNode       = connectionEdge.ToNode;
            var childNodeRecord = this.NodeRecordArray.GetNodeRecord(childNode);

            if (childNodeRecord == null)
            {
                //this piece of code is used just because of the special start nodes and goal nodes added to the RAIN Navigation graph when a new search is performed.
                //Since these special goals were not in the original navigation graph, they will not be stored in the NodeRecordArray and we will have to add them
                //to a special structure
                //it's ok if you don't understand this, this is a hack and not part of the NodeArrayA* algorithm, just do NOT CHANGE THIS, or your algorithm will not work
                childNodeRecord = new NodeRecord
                {
                    node   = childNode,
                    parent = bestNode,
                    status = NodeStatus.Unvisited
                };
                this.NodeRecordArray.AddSpecialCaseNode(childNodeRecord);
                return;
            }

            g = bestNode.gValue + (childNodeRecord.node.LocalPosition - bestNode.node.LocalPosition).magnitude;
            h = this.Heuristic.H(childNodeRecord.node, this.GoalNode);
            f = F(g, h);


            //childNodeRecord = GenerateChildNodeRecord(bestNode, connectionEdge);

            var childOpen   = this.Open.SearchInOpen(childNodeRecord);
            var childClosed = this.Closed.SearchInClosed(childNodeRecord);

            if (childNodeRecord.status == NodeStatus.Unvisited)
            {
                childNodeRecord = GenerateChildNodeRecord(bestNode, connectionEdge);
                Open.AddToOpen(childNodeRecord);
                int count = Open.CountOpen();
                if (this.MaxOpenNodes < count)
                {
                    this.MaxOpenNodes = count;
                }
            }

            else if (childNodeRecord.status == NodeStatus.Open && childOpen != null && childOpen.fValue > childNodeRecord.fValue)
            {
                childNodeRecord = GenerateChildNodeRecord(bestNode, connectionEdge);
                this.Open.Replace(childOpen, childNodeRecord);
            }

            else if (childNodeRecord.status == NodeStatus.Closed && childClosed != null && childClosed.fValue > childNodeRecord.fValue)
            {
                childNodeRecord = GenerateChildNodeRecord(bestNode, connectionEdge);
                this.Closed.RemoveFromClosed(childClosed);
                this.Open.AddToOpen(childNodeRecord);
            }
        }
        public virtual bool Search(out GlobalPath solution, bool returnPartialSolution = false)
        {
            solution = null;

            if (InitialTime == -1.0f)
            {
                InitialTime = Time.realtimeSinceStartup;
            }

            float finalTime = 0f;

            for (int i = 0; Open.CountOpen() > 0; ++i)
            {
                NodeRecord record = Open.GetBestAndRemove();

                if (i >= NodesPerSearch)
                {
                    if (returnPartialSolution)
                    {
                        solution = CalculateSolution(record, returnPartialSolution);
                    }

                    return(false);
                }

                // update debug information
                if (Open.CountOpen() > MaxOpenNodes)
                {
                    MaxOpenNodes = Open.CountOpen();
                }

                ++TotalProcessedNodes;

                if (record.node == GoalNode)
                {
                    solution = CalculateSolution(record, returnPartialSolution);
                    CleanUp();
                    finalTime           = Time.realtimeSinceStartup;
                    TotalProcessingTime = finalTime - InitialTime;
                    return(true);
                }

                Closed.AddToClosed(record);

                for (int e = 0; e < record.node.OutEdgeCount; ++e)
                {
                    ProcessChildNode(record, record.node.EdgeOut(e));
                }
            }

            CleanUp();
            finalTime           = Time.realtimeSinceStartup;
            TotalProcessingTime = finalTime - InitialTime;
            return(true);
        }
示例#5
0
        public bool Search(out GlobalPath solution, bool returnPartialSolution)
        {
            //TODO: implement this
            //to determine the connections of the selected nodeRecord you need to look at the NavigationGraphNode' EdgeOut  list
            //something like this
            //var outConnections = bestNode.node.OutEdgeCount;
            //for (int i = 0; i < outConnections; i++)
            //{
            //this.ProcessChildNode(bestNode, bestNode.node.EdgeOut(i));
            if (this.Open.CountOpen() == 0)
            {
                //Debug.Log("acabou1");
                solution = null;
                return(true);
            }
            var currentNode = Open.GetBestAndRemove();

            if (this.GoalNode == currentNode.node)
            {
                //Debug.Log("acabou2");
                solution = CalculateSolution(currentNode, false);
                return(true);
            }

            if (returnPartialSolution)
            {
                solution = CalculateSolution(currentNode, true);
                return(true);
            }

            this.Closed.AddToClosed(currentNode);
            this.TotalExploredNodes += 1;

            uint outConnections = (uint)currentNode.node.OutEdgeCount;

            if (outConnections > this.NodesPerFrame)
            {
                outConnections = this.NodesPerFrame; //setting nodes visited each frame
            }

            if (Open.CountOpen() > this.MaxOpenNodes)
            {
                this.MaxOpenNodes = Open.CountOpen();
            }

            for (int i = 0; i < outConnections; i++)
            {
                this.ProcessChildNode(currentNode, currentNode.node.EdgeOut(i), i);
            }

            this.TotalProcessingTime += Time.deltaTime; //check later
            solution = null;
            return(false);
        }
示例#6
0
        public bool Search(out GlobalPath solution, bool returnPartialSolution = false)
        {
            var startTime = Time.realtimeSinceStartup;
            int counter   = 0;

            while (true)
            {
                if (Open.CountOpen() == 0)
                {
                    solution             = null;
                    TotalProcessingTime += Time.realtimeSinceStartup - startTime;
                    CleanUp();
                    return(true);
                }
                NodeRecord bestNode = Open.GetBestAndRemove();
                if (bestNode.node.Equals(GoalNode))
                {
                    solution             = CalculateSolution(bestNode, false);
                    this.InProgress      = false;
                    TotalProcessingTime += Time.realtimeSinceStartup - startTime;
                    CleanUp();
                    return(true);
                }
                Closed.AddToClosed(bestNode);

                //to determine the connections of the selected nodeRecord you need to look at the NavigationGraphNode' EdgeOut  list
                //something like this
                var outConnections = bestNode.node.OutEdgeCount;
                for (int i = 0; i < outConnections; i++)
                {
                    this.ProcessChildNode(bestNode, bestNode.node.EdgeOut(i));
                }
                if (counter >= NodesPerSearch)
                {
                    TotalProcessingTime += Time.realtimeSinceStartup - startTime;
                    solution             = CalculateSolution(bestNode, true);
                    return(false);
                }
                counter             += 1;
                TotalProcessedNodes += 1;
                if (MaxOpenNodes <= Open.CountOpen())
                {
                    MaxOpenNodes = Open.CountOpen();
                }
            }
        }
示例#7
0
        public void Search(NavigationGraphNode startNode, NodeGoalBounds nodeGoalBounds)
        {
            //TODO: Implement the algorithm that calculates the goal bounds using a dijkstra
            //Given that the nodes in the graph correspond to the edges of a polygon, we won't be able to use the vertices of the polygon to update the bounding boxes
            this.Open.Initialize();
            this.Closed.Initialize();

            //Initialize starting node for Dijkstra
            NodeRecord StartNode = NodeRecordArray.GetNodeRecord(startNode);

            StartNode.gValue = 0;
            StartNode.StartNodeOutConnectionIndex = -1; // -1 corresponds to not having a "color". Valid indices will start at 0
            Open.AddToOpen(StartNode);

            //Dijkstra
            while (Open.CountOpen() > 0)
            {
                NodeRecord currentNode = Open.GetBestAndRemove();

                Open.RemoveFromOpen(currentNode);
                Closed.AddToClosed(currentNode);

                //We don't fill out the starting position as it is colorless
                if (currentNode.StartNodeOutConnectionIndex != -1)
                {
                    var outFillConnections = currentNode.node.OutEdgeCount;

                    Vector3 edgePosition;
                    //Update the bounding box with all positions of EdgeOuts of the current Node
                    for (int i = 0; i < outFillConnections; i++)
                    {
                        edgePosition = currentNode.node.EdgeOut(i).ToNode.Position;
                        nodeGoalBounds.connectionBounds[currentNode.StartNodeOutConnectionIndex].UpdateBounds(edgePosition); //update only the bound corresponding to the ConnectionIndex
                    }
                }

                //Process Child Nodes
                var outConnections = currentNode.node.OutEdgeCount;
                for (int i = 0; i < outConnections; i++)
                {
                    this.ProcessChildNode(currentNode, currentNode.node.EdgeOut(i), i);
                }
            }
        }
        public bool Search(out GlobalPath solution, bool returnPartialSolution = false)
        {
            //TODO: implement this
            //to determine the connections of the selected nodeRecord you need to look at the NavigationGraphNode' EdgeOut  list
            //something like this
            int        nodesVisited = 0;
            NodeRecord bestNode;

            while (this.Open.CountOpen() > 0)
            {
                if (Open.CountOpen() > MaxOpenNodes)
                {
                    MaxOpenNodes = Open.CountOpen();
                }

                bestNode = this.Open.GetBestAndRemove();
                this.Closed.AddToClosed(bestNode);
                if (bestNode.node.Equals(GoalNode))
                {
                    solution             = CalculateSolution(bestNode, false);
                    TotalProcessingTime += Time.deltaTime;
                    CleanUp();
                    InProgress = false;
                    return(true);
                }
                for (int i = 0; i < bestNode.node.OutEdgeCount; i++)
                {
                    this.ProcessChildNode(bestNode, bestNode.node.EdgeOut(i), i);
                }
                nodesVisited++;
                TotalExploredNodes++;
                if (returnPartialSolution && nodesVisited == NodesPerFrame)
                {
                    solution             = CalculateSolution(bestNode, true);
                    TotalProcessingTime += Time.deltaTime;
                    return(false);
                }
            }
            CleanUp();
            InProgress           = false;
            solution             = null;
            TotalProcessingTime += Time.deltaTime;
            return(true);
        }
示例#9
0
        public bool Search(out GlobalPath solution, bool returnPartialSolution = false)
        {
            var openCount = Open.CountOpen();

            solution = null;
            for (int j = 0; j < this.NodesPerFrame; j++)
            {
                if (openCount == 0)
                {
                    solution                  = null;
                    this.InProgress           = false;
                    this.TotalProcessingTime += Time.time;
                    return(true);
                }
                var bestNode = Open.GetBestAndRemove();
                this.TotalExploredNodes++;
                Closed.AddToClosed(bestNode);
                if (bestNode.node.Equals(GoalNode))
                {
                    solution                  = CalculateSolution(bestNode, false);
                    this.InProgress           = false;
                    this.TotalProcessingTime += Time.time;
                    return(true);
                }
                var outConnections = bestNode.node.OutEdgeCount;
                for (int i = 0; i < outConnections; i++)
                {
                    this.ProcessChildNode(bestNode, bestNode.node.EdgeOut(i), i);
                }
                openCount = this.Open.CountOpen();
                if (openCount > this.MaxOpenNodes)
                {
                    this.MaxOpenNodes = openCount;
                }
            }
            if (returnPartialSolution)
            {
                solution = CalculateSolution(Open.PeekBest(), true);
            }
            return(false);
        }
        public void Search(NavigationGraphNode startNode, NodeGoalBounds nodeGoalBounds)
        {
            this.Open.Initialize();
            this.Closed.Initialize();

            StartNode = startNode;
            var startNodeRecord = this.NodeRecordArray.GetNodeRecord(startNode);

            startNodeRecord.gValue = 0;
            startNodeRecord.hValue = 0;
            startNodeRecord.fValue = F(startNodeRecord);
            Closed.AddToClosed(startNodeRecord);

            var outConnectionsStart = startNodeRecord.node.OutEdgeCount;

            for (int i = 0; i < outConnectionsStart; i++)
            {
                ProcessChildNode(startNodeRecord, startNodeRecord.node.EdgeOut(i), i);

                NavigationGraphNode childNode = startNodeRecord.node.EdgeOut(i).ToNode;
                var childNodeRecord           = this.NodeRecordArray.GetNodeRecord(childNode);
                nodeGoalBounds.connectionBounds[i].InitializeBounds(childNodeRecord.node.LocalPosition);
            }

            while (Open.CountOpen() > 0)
            {
                var bestNode = Open.GetBestAndRemove();
                this.Closed.AddToClosed(bestNode);
                //UnityEngine.Debug.Log("Parent index: " + bestNode.StartNodeOutConnectionIndex);
                nodeGoalBounds.connectionBounds[bestNode.StartNodeOutConnectionIndex].UpdateBounds(bestNode.node.LocalPosition);
                var outConnections = bestNode.node.OutEdgeCount;
                for (int i = 0; i < outConnections; i++)
                {
                    ProcessChildNode(bestNode, bestNode.node.EdgeOut(i), bestNode.StartNodeOutConnectionIndex);
                }
            }
        }
示例#11
0
 public int CountOpen()
 {
     return Open.CountOpen();
 }
示例#12
0
        //this method should return true if it finished processing, and false if it still needs to continue
        public bool MapFloodDijkstra()
        {
            var processedNodes = 0;

            while (Open.CountOpen() > 0)
            {
                processedNodes++;

                if (processedNodes > NodesPerFlood)
                {
                    return(false);
                }
                LocationRecord currentRecord = Open.GetBestAndRemove();
                Closed.AddToClosed(currentRecord);

                int outConnections = currentRecord.Location.OutEdgeCount;
                for (int i = 0; i < outConnections; i++)
                {
                    var   location  = GenerateChildNodeRecord(currentRecord, currentRecord.Location.EdgeOut(i));
                    float influence = InfluenceFunction.DetermineInfluence(currentRecord.StrongestInfluenceUnit, location.Location.Position);

                    if (InfluenceThreshold.CompareTo(influence) > 0)
                    {
                        continue;
                    }

                    LocationRecord neighborRecord = Closed.SearchInClosed(location);

                    if (neighborRecord != null)
                    {
                        if (neighborRecord.Influence >= influence)
                        {
                            continue;
                        }
                        else
                        {
                            Closed.RemoveFromClosed(neighborRecord);
                        }
                    }
                    else
                    {
                        neighborRecord = Open.SearchInOpen(location);

                        if (neighborRecord != null)
                        {
                            if (neighborRecord.Influence < influence)
                            {
                                neighborRecord.StrongestInfluenceUnit = currentRecord.StrongestInfluenceUnit;
                                neighborRecord.Influence = influence;
                            }
                            continue;
                        }
                        else //we found a new record not in open or closed
                        {
                            neighborRecord          = new LocationRecord();
                            neighborRecord.Location = location.Location;
                        }
                    }

                    neighborRecord.StrongestInfluenceUnit = currentRecord.StrongestInfluenceUnit;
                    neighborRecord.Influence = influence;
                    Open.AddToOpen(neighborRecord);
                }
            }

            this.InProgress = false;
            //this.CleanUp();
            return(true);
        }
示例#13
0
        public bool Search(out GlobalPath solution, bool returnPartialSolution = false)
        {
            var time           = UnityEngine.Time.realtimeSinceStartup;
            var nodesprocessed = 0;
            var maximumOpen    = 0;



            //to determine the connections of the selected nodeRecord you need to look at the NavigationGraphNode' EdgeOut  list
            //something like this

            while (true)
            {
                if (Open.CountOpen() > maximumOpen)
                {
                    maximumOpen = Open.CountOpen();
                }

                if (Open.CountOpen() == 0)
                {
                    solution             = null;
                    InProgress           = false;
                    TotalProcessedNodes += (uint)nodesprocessed;
                    TotalProcessingTime  = UnityEngine.Time.realtimeSinceStartup - time;
                    MaxOpenNodes         = maximumOpen;
                    return(true);
                }

                NodeRecord bestNode = Open.GetBestAndRemove();

                if (nodesprocessed > NodesPerSearch)
                {
                    if (returnPartialSolution)
                    {
                        solution = CalculateSolution(bestNode, returnPartialSolution);
                    }
                    else
                    {
                        solution = null;
                    }
                    InProgress           = true;
                    TotalProcessedNodes += (uint)nodesprocessed;
                    TotalProcessingTime  = UnityEngine.Time.realtimeSinceStartup - time;
                    MaxOpenNodes         = maximumOpen;
                    return(false);
                }


                if (bestNode.node == GoalNode)
                {
                    solution             = CalculateSolution(bestNode, false);
                    InProgress           = false;
                    TotalProcessedNodes += (uint)nodesprocessed;
                    TotalProcessingTime  = UnityEngine.Time.realtimeSinceStartup - time;
                    MaxOpenNodes         = maximumOpen;
                    return(true);
                }

                Closed.AddToClosed(bestNode);
                nodesprocessed++;


                //
                //TODO put your code here
                //or if you would like, you can change just these lines of code this in the original A* Pathfinding Base Class,
                //create a ProcessChildNode method in the base class with the code from the previous A* algorithm.
                //if you do this, then you don't need to implement this search method method. Just delete this and don't forget to override the ProcessChildMethod if you do this
                var outConnections = bestNode.node.OutEdgeCount;
                for (int i = 0; i < outConnections; i++)
                {
                    this.ProcessChildNode(bestNode, bestNode.node.EdgeOut(i));
                }
            }
        }
示例#14
0
        public bool Search(out GlobalPath solution, bool returnPartialSolution = false)
        {
            //TODO put the code from the previous LAB here
            //you will get compiler errors, because I change the method names in the IOpenSet and IClosedSet interfaces
            //sorry but I had to do it because if not, Unity profiler would consider the Search method in Open and Closed to be the same
            //and you would not be able to see the difference in performance searching the Open Set and in searching the closed set

            //so just replace this.Open.Search(...) by this.Open.SearchInOpen(...) and all other methods where you get the compilation errors

            var   CurrentSearchNodes = 0;
            var   NodesProcessed     = 0;
            var   MaxOpenSize        = 0;
            float StartTime          = Time.realtimeSinceStartup;

            while (true)
            {
                if (Open.CountOpen() > MaxOpenSize)
                {
                    MaxOpenSize = Open.CountOpen();
                }

                if (Open.CountOpen() == 0)
                {
                    solution            = null;
                    TotalProcessedNodes = (uint)NodesProcessed;
                    MaxOpenNodes        = MaxOpenSize;
                    this.InProgress     = false;
                    TotalProcessingTime = Time.realtimeSinceStartup - StartTime;
                    return(true);
                }


                if (NodesPerSearch < CurrentSearchNodes)
                {
                    if (returnPartialSolution)
                    {
                        solution = CalculateSolution(this.Open.PeekBest(), returnPartialSolution);
                    }
                    else
                    {
                        solution = null;
                    }

                    TotalProcessedNodes = (uint)NodesProcessed;
                    MaxOpenNodes        = MaxOpenSize;
                    TotalProcessingTime = Time.realtimeSinceStartup - StartTime;
                    return(false);
                }

                NodeRecord CurrentNode = Open.GetBestAndRemove();

                if (CurrentNode.node == GoalNode)
                {
                    InProgress          = false;
                    TotalProcessedNodes = (uint)NodesProcessed;
                    MaxOpenNodes        = MaxOpenSize;
                    TotalProcessingTime = Time.realtimeSinceStartup - StartTime;
                    solution            = CalculateSolution(CurrentNode, false);
                    return(true);
                }

                Closed.AddToClosed(CurrentNode);
                CurrentSearchNodes++;
                NodesProcessed++;
                var NodeActions = CurrentNode.node.OutEdgeCount;

                for (int i = 0; i < NodeActions; i++)
                {
                    ProcessChildNode(CurrentNode, CurrentNode.node.EdgeOut(i));
                }
            }
        }