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;
            }
        }
예제 #2
0
        public void Initialize(List <IInfluenceUnit> units)
        {
            this.Open.Initialize();
            this.Closed.Initialize();
            this.Units = units;

            foreach (var unit in units)
            {
                //I need to do this because in Recast NavMesh graph, the edges of polygons are considered to be nodes and not the connections.
                //Theoretically the Quantize method should then return the appropriate edge, but instead it returns a polygon
                //Therefore, we need to create one explicit connection between the polygon and each edge of the corresponding polygon for the search algorithm to work
                ((NavMeshPoly)unit.Location).AddConnectedPoly(unit.Location.Position);

                var locationRecord = new LocationRecord
                {
                    Influence = unit.DirectInfluence,
                    StrongestInfluenceUnit = unit,
                    Location = unit.Location
                };

                Open.AddToOpen(locationRecord);
            }

            this.InProgress = true;
        }
예제 #3
0
        protected void ProcessChildNode(NodeRecord parent, NavigationGraphEdge connectionEdge, int connectionIndex)
        {
            //TODO: Implement this method that processes a child node. Then you can use it in the Search method above.
            var childNode       = connectionEdge.ToNode;
            var childNodeRecord = this.NodeRecordArray.GetNodeRecord(childNode);

            //Distribute initial colors throughout startNode children:
            int startIndex = parent.StartNodeOutConnectionIndex;

            if (startIndex == -1)
            {
                startIndex = connectionIndex;
            }

            float      g            = parent.gValue + (childNode.LocalPosition - parent.node.LocalPosition).magnitude;
            NodeRecord nodeInOpen   = Open.SearchInOpen(childNodeRecord);
            NodeRecord nodeInClosed = Closed.SearchInClosed(childNodeRecord);

            if (nodeInOpen == null && nodeInClosed == null)
            {
                childNodeRecord.parent = parent;
                childNodeRecord.gValue = g;
                childNodeRecord.fValue = g;
                childNodeRecord.StartNodeOutConnectionIndex = startIndex;
                Open.AddToOpen(childNodeRecord);
            }
            else if (nodeInOpen != null && nodeInOpen.gValue > g)
            {
                childNodeRecord.parent = parent;
                childNodeRecord.gValue = g;
                childNodeRecord.fValue = g;
                childNodeRecord.StartNodeOutConnectionIndex = startIndex;
                Open.Replace(nodeInOpen, childNodeRecord);
            }
        }
        protected virtual void ProcessChildNode(NodeRecord parentNode, NavigationGraphEdge connectionEdge, int connectionIndex)
        {
            //this is where you process a child node
            var childNode = GenerateChildNodeRecord(parentNode, connectionEdge);

            NodeRecord openNode  = Open.SearchInOpen(childNode);
            NodeRecord closeNode = Closed.SearchInClosed(childNode);

            if (openNode == null && closeNode == null)
            {
                this.Open.AddToOpen(childNode);
            }
            else if (openNode != null && childNode.fValue < openNode.fValue)
            {
                Open.Replace(openNode, childNode);
            }
            else if (openNode != null && childNode.fValue == openNode.fValue)
            {
                if (childNode.hValue < openNode.hValue)
                {
                    Open.Replace(openNode, childNode);
                }
            }
            else if (closeNode != null && childNode.fValue < closeNode.fValue)
            {
                Closed.RemoveFromClosed(closeNode);
                Open.AddToOpen(childNode);
            }
        }
예제 #5
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();


            NodeRecord StartNode = NodeRecordArray.GetNodeRecord(startNode);

            StartNode.StartNodeOutConnectionIndex = -1;
            Open.AddToOpen(StartNode);
            int OpenSize = Open.All().Count;

            while (OpenSize > 0)
            {
                NodeRecord currentNode = Open.GetBestAndRemove();
                Open.RemoveFromOpen(currentNode);
                Closed.AddToClosed(currentNode);
                if (currentNode.StartNodeOutConnectionIndex != -1)
                {
                    nodeGoalBounds.connectionBounds[currentNode.StartNodeOutConnectionIndex].UpdateBounds(currentNode.node.Position);
                }

                //Initialize start node edge colors:
                var outConnections = currentNode.node.OutEdgeCount;
                for (int i = 0; i < outConnections; i++)
                {
                    this.ProcessChildNode(currentNode, currentNode.node.EdgeOut(i), i);
                }
                OpenSize = Open.All().Count;
            }
        }
예제 #6
0
        protected virtual void ProcessChildNode(NodeRecord parentNode, NavigationGraphEdge connectionEdge, int edgeIndex)
        {
            //this is where you process a child node
            var childNode = GenerateChildNodeRecord(parentNode, connectionEdge);
            //TODO: implement the rest of the code here
            var nodeOpen  = Open.SearchInOpen(childNode);
            var nodeClose = Closed.SearchInClosed(childNode);

            if (nodeOpen != null)
            {
                if (nodeOpen.fValue >= childNode.fValue)
                {
                    Open.RemoveFromOpen(nodeOpen);
                    Open.AddToOpen(childNode);
                }
                return;
            }
            else if (nodeClose != null)
            {
                if (nodeClose.fValue > childNode.fValue)
                {
                    Closed.RemoveFromClosed(nodeClose);
                    Open.AddToOpen(childNode);
                }
                return;
            }
            Open.AddToOpen(childNode);
        }
        protected virtual void ProcessChildNode(NodeRecord parent, NavigationGraphEdge connectionEdge)
        {
            var childNode       = connectionEdge.ToNode;
            var childNodeRecord = new NodeRecord
            {
                node   = childNode,
                parent = parent,
                gValue = parent.gValue + connectionEdge.Cost,
                hValue = this.Heuristic.H(childNode, this.GoalNode)
            };

            childNodeRecord.fValue = F(childNodeRecord);
            NodeRecord openNode   = Open.SearchInOpen(childNodeRecord);
            NodeRecord closedNode = Closed.SearchInClosed(childNodeRecord);

            if (openNode == null && closedNode == null)
            {
                Open.AddToOpen(childNodeRecord);
            }
            else if (openNode != null && openNode.fValue > childNodeRecord.fValue)
            {
                Open.Replace(openNode, childNodeRecord);
            }
            else if (closedNode != null && closedNode.fValue > childNodeRecord.fValue)
            {
                Closed.RemoveFromClosed(closedNode);
                Open.AddToOpen(childNodeRecord);
            }
        }
        protected void ProcessChildNode(NodeRecord parent, NavigationGraphEdge connectionEdge, int connectionIndex)
        {
            NavigationGraphNode childNode = connectionEdge.ToNode;
            var childNodeRecord           = this.NodeRecordArray.GetNodeRecord(childNode);

            var open  = Open.SearchInOpen(childNodeRecord);
            var close = Closed.SearchInClosed(childNodeRecord);

            if (open == null && close == null)
            {
                float g = parent.gValue + (childNodeRecord.node.LocalPosition - parent.node.LocalPosition).magnitude;

                UpdateNode(parent, childNodeRecord, g, 0, g, connectionIndex);
                Open.AddToOpen(childNodeRecord);
            }
            else if (open != null)
            {
                var g = parent.gValue + (childNodeRecord.node.LocalPosition - parent.node.LocalPosition).magnitude;

                if (g < childNodeRecord.gValue)
                {
                    UpdateNode(parent, childNodeRecord, g, 0, g, connectionIndex);
                    Open.Replace(childNodeRecord, childNodeRecord);
                }
            }
        }
        public void Search(NavigationGraphNode startNode, NodeGoalBounds nodeGoalBounds)
        {
            this.Open.Initialize();
            this.Closed.Initialize();

            NodeRecord startNodeRecord = this.NodeRecordArray.GetNodeRecord(startNode);

            startNodeRecord.gValue = 0;
            startNodeRecord.fValue = 0;
            startNodeRecord.parent = null;
            startNodeRecord.StartNodeOutConnectionIndex = 0;
            Open.AddToOpen(startNodeRecord);

            while (true)
            {
                if (this.Open.CountOpen() == 0)
                {
                    return;
                }

                NodeRecord currNode = this.Open.GetBestAndRemove();
                this.Closed.AddToClosed(currNode);
                nodeGoalBounds.connectionBounds[currNode.StartNodeOutConnectionIndex].UpdateBounds(currNode.node.Position);

                int nOutConnections = currNode.node.OutEdgeCount;
                for (int i = 0; i < nOutConnections; i++)
                {
                    this.ProcessChildNode(currNode, currNode.node.EdgeOut(i), i);
                }
            }
            //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
        }
예제 #10
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);
            }
        }
예제 #11
0
        protected override void ProcessChildNode(NodeRecord bestNode, NavigationGraphEdge connectionEdge)
        {
            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 you algorithm wont work
                childNodeRecord = new NodeRecord
                {
                    node   = childNode,
                    parent = bestNode,
                    status = NodeStatus.Unvisited
                };
                this.NodeRecordArray.AddSpecialCaseNode(childNodeRecord);
            }

            g = bestNode.gValue + connectionEdge.Cost;
            h = this.Heuristic.H(childNode, this.GoalNode);
            f = g + h;

            var ChildNodeOpen   = Open.SearchInOpen(childNodeRecord);
            var ChildNodeClosed = Closed.SearchInClosed(childNodeRecord);

            if ((ChildNodeClosed == null) && (ChildNodeOpen == null))
            {
                childNodeRecord.parent = bestNode;
                childNodeRecord.gValue = g;
                childNodeRecord.hValue = h;
                childNodeRecord.fValue = f;
                Open.AddToOpen(childNodeRecord);
            }
            else if ((ChildNodeOpen != null) && f < childNodeRecord.fValue)
            {
                childNodeRecord.parent = bestNode;
                childNodeRecord.gValue = g;
                childNodeRecord.hValue = h;
                childNodeRecord.fValue = f;
                Open.Replace(ChildNodeOpen, childNodeRecord);
            }
            else if ((ChildNodeClosed != null) && f < childNodeRecord.fValue)
            {
                childNodeRecord.parent = bestNode;
                childNodeRecord.gValue = g;
                childNodeRecord.hValue = h;
                childNodeRecord.fValue = f;
                Open.AddToOpen(childNodeRecord);
            }
        }
예제 #12
0
        protected void ProcessChildNode(NodeRecord parent, NavigationGraphEdge connectionEdge, int connectionIndex)
        {
            //TODO: Implement this method that processes a child node. Then you can use it in the Search method above.
            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 = parent,
                    StartNodeOutConnectionIndex = parent.StartNodeOutConnectionIndex,
                    status = NodeStatus.Unvisited
                };
                this.NodeRecordArray.AddSpecialCaseNode(childNodeRecord);
            }

            //Distribute initial colors throughout startNode children:
            int color = parent.StartNodeOutConnectionIndex;

            if (color == -1)
            {
                color = connectionIndex;
            }
            NodeRecord parentNode   = parent;
            float      g            = parentNode.gValue + (childNode.LocalPosition - parentNode.node.LocalPosition).magnitude;
            NodeRecord nodeInOpen   = Open.SearchInOpen(childNodeRecord);
            NodeRecord nodeInClosed = Closed.SearchInClosed(childNodeRecord);

            if (nodeInOpen == null && nodeInClosed == null)
            {
                childNodeRecord.parent = parent;
                childNodeRecord.gValue = g;
                childNodeRecord.StartNodeOutConnectionIndex = color;
                Open.AddToOpen(childNodeRecord);
            }
            else if (nodeInOpen != null && childNodeRecord.gValue > g)
            {
                childNodeRecord.parent = parent;
                childNodeRecord.gValue = g;
                childNodeRecord.StartNodeOutConnectionIndex = color;
                Open.Replace(nodeInOpen, childNodeRecord);
            }
        }
예제 #13
0
        protected override void ProcessChildNode(NodeRecord bestNode, NavigationGraphEdge connectionEdge, int edgeIndex)
        {
            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);
            }

            //this is where you process a child node
            var parent = bestNode;
            var g      = bestNode.gValue + (childNode.LocalPosition - bestNode.node.LocalPosition).magnitude;
            var h      = this.Heuristic.H(childNode, this.GoalNode);
            //var h = this.Heuristic.Fast_H(childNode.Position, this.GoalNode.Position);
            var f = F(g, h);


            NodeRecord nodeInOpen   = Open.SearchInOpen(childNodeRecord);
            NodeRecord nodeInClosed = Closed.SearchInClosed(childNodeRecord);

            if (nodeInOpen == null && nodeInClosed == null)
            {
                childNodeRecord.parent = parent;
                childNodeRecord.gValue = g;
                childNodeRecord.hValue = h;
                childNodeRecord.fValue = f;
                Open.AddToOpen(childNodeRecord);
            }
            else if (nodeInOpen != null && nodeInOpen.fValue > f)
            {
                childNodeRecord.parent = parent;
                childNodeRecord.gValue = g;
                childNodeRecord.hValue = h;
                childNodeRecord.fValue = f;
                Open.Replace(nodeInOpen, childNodeRecord);
            }
        }
예제 #14
0
        protected virtual void ProcessChildNode(NodeRecord parentNode, NavigationGraphEdge connectionEdge, int edgeIndex)
        {
            //this is where you process a child node
            var        childNode    = GenerateChildNodeRecord(parentNode, connectionEdge);
            NodeRecord nodeInOpen   = Open.SearchInOpen(childNode);
            NodeRecord nodeInClosed = Closed.SearchInClosed(childNode);

            if (nodeInOpen == null && nodeInClosed == null)
            {
                Open.AddToOpen(childNode);
            }
            else if (nodeInOpen != null && childNode.fValue < nodeInOpen.fValue)
            {
                Open.Replace(nodeInOpen, childNode);
            }
        }
        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);
            }

            //TODO: implement the rest of your code here
            //this is where you process a child node
            childNodeRecord = GenerateChildNodeRecord(bestNode, connectionEdge);

            var openChildNode   = Open.SearchInOpen(childNodeRecord);
            var closedChildNode = Closed.SearchInClosed(childNodeRecord);

            if (openChildNode == null && closedChildNode == null)
            {
                Open.AddToOpen(childNodeRecord);
            }
            else if (openChildNode != null && openChildNode.fValue > childNodeRecord.fValue)
            {
                Open.Replace(openChildNode, childNodeRecord);
            }
            else if (closedChildNode != null && closedChildNode.fValue > childNodeRecord.fValue)
            {
                //Closed.RemoveFromClosed(closedChildNode);
                Open.AddToOpen(childNodeRecord);
            }
        }
예제 #16
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);
                }
            }
        }
예제 #17
0
        protected virtual void ProcessChildNode(NodeRecord bestNode, NavigationGraphEdge connectionEdge)
        {
            var childNodeRecord    = GenerateChildNodeRecord(bestNode, connectionEdge);
            var oldChildNodeOpen   = Open.SearchInOpen(childNodeRecord);
            var oldChildNodeClosed = Closed.SearchInClosed(childNodeRecord);

            if ((oldChildNodeClosed == null) && (oldChildNodeOpen == null))
            {
                Open.AddToOpen(childNodeRecord);
            }
            else if ((oldChildNodeOpen != null) && oldChildNodeOpen.fValue > childNodeRecord.fValue)
            {
                Open.Replace(oldChildNodeOpen, childNodeRecord);
            }
            else if ((oldChildNodeClosed != null) && oldChildNodeClosed.fValue > childNodeRecord.fValue)
            {
                Closed.RemoveFromClosed(oldChildNodeClosed);
                Open.AddToOpen(childNodeRecord);
            }
        }
예제 #18
0
        //don't forget to add the override keyword here if you define a ProcessChildNode method in the base class
        protected void ProcessChildNode(NodeRecord bestNode, NavigationGraphEdge connectionEdge)
        {
            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 you algorithm wont work
                childNodeRecord = new NodeRecord
                {
                    node   = childNode,
                    parent = bestNode,
                    status = NodeStatus.Unvisited
                };
                this.NodeRecordArray.AddSpecialCaseNode(childNodeRecord);
            }

            childNodeRecord.gValue = bestNode.gValue + connectionEdge.Cost;
            childNodeRecord.hValue = this.Heuristic.H(childNode, this.GoalNode);
            childNodeRecord.fValue = F(childNodeRecord);

            NodeRecord openNode   = Open.SearchInOpen(childNodeRecord);
            NodeRecord closedNode = Closed.SearchInClosed(childNodeRecord);

            if (openNode == null && closedNode == null)
            {
                Open.AddToOpen(childNodeRecord);
            }
            else if (openNode != null && openNode.fValue > childNodeRecord.fValue)
            {
                Open.Replace(openNode, childNodeRecord);
            }
            else if (closedNode != null && closedNode.fValue > childNodeRecord.fValue)
            {
                Closed.RemoveFromClosed(closedNode);
                Open.AddToOpen(childNodeRecord);
            }
        }
예제 #19
0
        protected virtual void ProcessChildNode(NodeRecord bestNode, NavigationGraphEdge connectionEdge)
        {
            //this is where you process a child node
            var ChildNode       = GenerateChildNodeRecord(bestNode, connectionEdge);
            var ChildNodeOpen   = Open.SearchInOpen(ChildNode);
            var ChildNodeClosed = Closed.SearchInClosed(ChildNode);

            if ((ChildNodeClosed == null) && (ChildNodeOpen == null))
            {
                Open.AddToOpen(ChildNode);
            }
            else if ((ChildNodeOpen != null) && ChildNodeOpen.fValue >= ChildNode.fValue)
            {
                Open.Replace(ChildNodeOpen, ChildNode);
            }
            else if ((ChildNodeClosed != null) && ChildNodeClosed.fValue > ChildNode.fValue)
            {
                Closed.RemoveFromClosed(ChildNodeClosed);
                Open.AddToOpen(ChildNode);
            }
        }
        protected void ProcessChildNode(NodeRecord parent, NavigationGraphEdge connectionEdge, int connectionIndex)
        {
            var childNode = connectionEdge.ToNode;
            //TODO: implement the rest of your code here
            //this is where you process a child node
            var gValue = parent.gValue + (childNode.LocalPosition - parent.node.LocalPosition).magnitude;


            var childNodeRecord = new NodeRecord
            {
                node   = childNode,
                parent = parent,
                gValue = gValue,
                fValue = gValue
            };

            if (parent.parent == null)
            {
                childNodeRecord.StartNodeOutConnectionIndex = connectionIndex;
            }
            else
            {
                childNodeRecord.StartNodeOutConnectionIndex = parent.StartNodeOutConnectionIndex;
            }

            var openChildNode   = Open.SearchInOpen(childNodeRecord);
            var closedChildNode = Closed.SearchInClosed(childNodeRecord);

            if (openChildNode == null && closedChildNode == null)
            {
                Open.AddToOpen(childNodeRecord);
            }
            else if (openChildNode != null && openChildNode.fValue > childNodeRecord.fValue)
            {
                Open.Replace(openChildNode, childNodeRecord);
            }

            //TODO: Implement this method that processes a child node. Then you can use it in the Search method above.
        }
예제 #21
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
            startNodeRecord = this.NodeRecordArray.GetNodeRecord(startNode);
            startNodeIndex  = startNodeRecord.node.NodeIndex;
            startNodeRecord.startNodeIndex = startNodeIndex;

            bool first = true;

            Open.AddToOpen(startNodeRecord);

            while (this.Open.CountOpen() > 0)
            {
                bestNode = this.Open.GetBestAndRemove();

                if (!first)
                {
                    nodeGoalBounds.connectionBounds[bestNode.StartNodeOutConnectionIndex].UpdateBounds(bestNode.node.Position);
                }

                this.Closed.AddToClosed(bestNode);

                for (int i = 0; i < bestNode.node.OutEdgeCount; i++)
                {
                    if (first)
                    {
                        this.ProcessChildNode(bestNode, bestNode.node.EdgeOut(i), i, nodeGoalBounds);
                    }
                    else
                    {
                        this.ProcessChildNode(bestNode, bestNode.node.EdgeOut(i), bestNode.StartNodeOutConnectionIndex, nodeGoalBounds);
                    }
                }
                first = false;
            }
        }
예제 #22
0
        protected virtual void ProcessChildNode(NodeRecord bestNode, NavigationGraphEdge connectionEdge)
        {
            //this is where you process a child node
            NodeRecord childNode  = GenerateChildNodeRecord(bestNode, connectionEdge);
            NodeRecord openNode   = Open.SearchInOpen(childNode);
            NodeRecord closedNode = Closed.SearchInClosed(childNode);
            bool       inOpen     = openNode != null ? true : false;
            bool       inClosed   = closedNode != null ? true : false;

            if (!inOpen && !inClosed)
            {
                Open.AddToOpen(childNode);
            }
            else if (inOpen && childNode.fValue < openNode.fValue)
            {
                Open.RemoveFromOpen(openNode);
                Open.AddToOpen(childNode);
            }
            else if (inClosed && childNode.fValue < closedNode.fValue)
            {
                Closed.RemoveFromClosed(closedNode);
                Open.AddToOpen(childNode);
            }
        }
예제 #23
0
        public void AddToOpen(NodeRecord nodeRecord)
        {
            Open.AddToOpen(nodeRecord);

            NodeRecords[nodeRecord.node.NodeIndex].status = NodeStatus.Open;
        }
예제 #24
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);

            #region do not look into this
            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);
            }
            #endregion

            h = this.Heuristic.H(childNode, this.GoalNode);
            g = bestNode.gValue + connectionEdge.Cost;
            f = g + h;

            NodeRecord nodeOpen   = this.Open.SearchInOpen(childNodeRecord);
            NodeRecord closedNode = this.Closed.SearchInClosed(childNodeRecord);

            if (nodeOpen != null)
            {
                if (nodeOpen.fValue >= f)
                {
                    Open.RemoveFromOpen(nodeOpen);
                    childNodeRecord.parent = bestNode;
                    childNodeRecord.gValue = g;
                    childNodeRecord.hValue = h;
                    childNodeRecord.fValue = f;
                    Open.AddToOpen(childNodeRecord);
                }
                return;
            }
            else if (closedNode != null)
            {
                if (closedNode.fValue > f)
                {
                    Closed.RemoveFromClosed(closedNode);
                    childNodeRecord.parent = bestNode;
                    childNodeRecord.gValue = g;
                    childNodeRecord.hValue = h;
                    childNodeRecord.fValue = f;
                    Open.AddToOpen(childNodeRecord);
                }
                return;
            }
            childNodeRecord.parent = bestNode;
            childNodeRecord.gValue = g;
            childNodeRecord.hValue = h;
            childNodeRecord.fValue = f;
            Open.AddToOpen(childNodeRecord);
        }
예제 #25
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);
        }