示例#1
0
 public override void Update(double elapsed)
 {
     _speedBoost -= BoostDecrement * elapsed;
     _speedBoost = _speedBoost < 1 ? 1 : _speedBoost;
     double distance = (Position - _current.Position).Length;
     if (distance < TargetDistance)
     {
         if (_enumerator.MoveNext())
         {
             _current = _enumerator.Current;
             // Recursion stops when we have a target that's far enough
             // to move towards.
             Update(elapsed);
         }
         else
         {
             // Time to explore again!
             Initialize();
         }
     }
     else
     {
         _steering.Location = _current.Position;
         Vector2 steeringForce = _steering.Steer(this, elapsed) * 3 * _speedBoost;
         Vector2 acceleration = steeringForce / Mass;
         Velocity += acceleration * elapsed;
         Velocity = Velocity.Truncate(MaxSpeed);
         Position += Velocity * elapsed * _speedBoost;
         UpdateSpriteDirection();
         UpdateSpriteAnimation(elapsed);
     }
 }
        public static Graph CreateGraph(
            int x, int y,
            int columns, int rows,
            float sizePerEdge)
        {
            Graph graph = new Graph();
            GraphNode[,] nodes = new GraphNode[columns, rows];

            // Create all GraphNodes.
            for (int i = 0; i < columns; i++)
            {
                for (int j = 0; j < rows; j++)
                {
                    double xPos = x * sizePerEdge + i * sizePerEdge;
                    double yPos = y * sizePerEdge + j * sizePerEdge;
                    nodes[i, j] = new GraphNode(new Vector2(xPos, yPos));
                }
            }

            // Create all GraphEdges and add them to the graph.
            for (int i = 0; i < columns; i++)
            {
                for (int j = 0; j < rows; j++)
                {
                    CreateEdges(graph, nodes, i, j, columns, rows);
                }
            }
            return graph;
        }
 public void ConnectedGraph_GetDepthFirstEnumerable_StartsWithStartNode()
 {
     Graph graph = new Graph();
     GraphNode start = new GraphNode(new Vector2(0, 0));
     GraphNode finish = new GraphNode(new Vector2(1, 1));
     graph.AddEdge(new GraphEdge(start, finish));
     var enumerator = graph.GetDepthFirstEnumerable(start).GetEnumerator();
     Assert.IsTrue(enumerator.Current == start,
         "Enumerator did not start with the correct node");
 }
 private static void CreateEdges(Graph graph, GraphNode[,] nodes, int x, int y,
     int columns, int rows)
 {
     for (int i = x - 1; i < x + 2; i++)
     {
         for (int j = y - 1; j < y + 2; j++)
         {
             if (i > 0 && i < columns && j > 0 && j < rows &&
                 !(i == x && j == y))
             {
                 graph.AddEdge(new GraphEdge(nodes[x, y], nodes[i, j]));
             }
         }
     }
 }
示例#5
0
 /// <summary>
 /// Recursive call for calculating the shortest path.
 /// </summary>
 /// <returns>Whether the current node is connected to the destination.</returns>
 private bool GetShortestPathRecursive(GraphNode current, GraphNode destination)
 {
     // Backtrack if we have found a path.
     if (current == destination)
     {
         return true;
     }
     foreach (GraphEdge edge in current.AdjecentEdges)
     {
         // If our current node is in the open list...
         if (_openList.Any(n => n == edge.Destination))
         {
             // Update best distance if we have a better distance.
             if (current.BestDistance + edge.Cost <
                 edge.Destination.BestDistance)
             {
                 edge.Destination.BestDistance =
                     current.BestDistance + edge.Cost;
                 edge.Destination.EstimatedDistance =
                     _heuristic.Calculate(edge.Destination);
                 edge.Destination.Parent = current;
             }
         }
         else if (!_closedList.Any(n => n == edge.Destination))
         {
             // Update best distance and add node to open list.
             edge.Destination.BestDistance =
                 current.BestDistance + edge.Cost;
             edge.Destination.EstimatedDistance =
                 _heuristic.Calculate(edge.Destination);
             edge.Destination.Parent = current;
             _openList.Add(edge.Destination);
         }
         _consideredEdges.Add(edge);
     }
     _openList.Remove(current);
     _closedList.Add(current);
     GraphNode next = _openList.FirstOrDefault(n =>
         n.Score == _openList.Min(ni => ni.Score)
     );
     if (next == null)
     {
         // Can't find a path, go back.
         return false;
     }
     return GetShortestPathRecursive(next, destination);
 }
        public void GraphWithDisconnectedNodes_GetShortestPath_ThrowsArgumentException()
        {
            GraphNode source = new GraphNode(new Vector2(0f, 0f));
            GraphNode destination = new GraphNode(new Vector2(10f, 10f));
            Graph disconnectedGraph = new Graph();
            disconnectedGraph.AddEdge(
                new GraphEdge(source, new GraphNode(new Vector2(1f, 1f)))
            );
            disconnectedGraph.AddEdge(
                new GraphEdge(new GraphNode(new Vector2(5f, 5f)), destination)
            );
            AStarAlgorithm astar = new AStarAlgorithm(disconnectedGraph);

            // Should throw an argument exception, because it cannot
            // calculate the shortest path between disconnected nodes.
            astar.GetShortestPath(source, destination);
        }
示例#7
0
 public ShortestPath GetShortestPath(GraphNode start, GraphNode destination)
 {
     Initialize(destination);
     start.BestDistance = 0f;
     _consideredEdges = new LinkedList<GraphEdge>();
     if (GetShortestPathRecursive(start, destination))
     {
         var path = new LinkedList<GraphNode>();
         GraphNode current = destination;
         path.AddFirst(current);
         while (current != start)
         {
             current = current.Parent;
             path.AddFirst(current);
         }
         return new ShortestPath(path.ToList(), _consideredEdges);
     }
     throw new ArgumentException("Startnode is not connected to destination node.");
 }
        public void ConnectedGraph_GetShortestPath_ReturnsCorrectPath()
        {
            // Create a graph with four nodes, connected in a straight line.
            Graph graph = new Graph();

            const int NodeCount = 4;
            GraphNode start = new GraphNode(new Vector2(0f, 0f));
            GraphNode midFirst = new GraphNode(new Vector2(1f, 1f));
            GraphNode midSecond = new GraphNode(new Vector2(2f, 2f));
            GraphNode destination = new GraphNode(new Vector2(3f, 3f));

            graph.AddEdge(new GraphEdge(start, midFirst));
            graph.AddEdge(new GraphEdge(midFirst, midSecond));
            graph.AddEdge(new GraphEdge(midSecond, destination));

            AStarAlgorithm astar = new AStarAlgorithm(graph);
            IEnumerable<GraphNode> path =
                astar.GetShortestPath(start, destination).Path;
            Assert.IsTrue(path.Count() == NodeCount,
                "Path has an invalid amount of nodes");
        }
 public void ConnectedGraph_GetDepthFirstEnumerable_TraversesCorrectAmountOfNodes()
 {
     const int EdgeCount = 4;
     const int NodeCount = EdgeCount + 1;
     Graph graph = new Graph();
     GraphNode start = new GraphNode(new Vector2());
     GraphNode currentSource = start;
     GraphNode currentDestination;
     for (int i = 0; i < EdgeCount; i++)
     {
         currentDestination = new GraphNode(new Vector2());
         graph.AddEdge(new GraphEdge(currentSource, currentDestination));
         currentSource = currentDestination;
     }
     var enumerator = graph.GetDepthFirstEnumerable(start).GetEnumerator();
     int actualCount = 1;
     while (enumerator.MoveNext())
     {
         actualCount++;
     }
     Assert.AreEqual(NodeCount, actualCount,
         "DeothFirstEnumerator did not traverse the correct amount of nodes.");
 }
示例#10
0
 private void Initialize()
 {
     GraphNode nearestNode = _graph.NearestNode(this.Position);
     _enumerator = _graph.GetDepthFirstEnumerable(nearestNode).GetEnumerator();
     _current = _enumerator.Current;
 }
示例#11
0
 private void Initialize(GraphNode destination)
 {
     this._openList = new LinkedList<GraphNode>();
     this._closedList = new LinkedList<GraphNode>();
     this._destination = destination;
     this._heuristic = new EuclideanDistanceHeuristic(destination);
 }
示例#12
0
 /// <summary>
 /// Returns an enumerator that uses the depth first algorithm to traverse
 /// this tree, starting at the specified start node.
 /// </summary>
 public IEnumerable<GraphNode> GetDepthFirstEnumerable(GraphNode startNode)
 {
     return new DepthFirstGraph(this, startNode);
 }
 public int Calculate(GraphNode node)
 {
     Vector2 distance = node.Position - _destination.Position;
     return (int)distance.Length;
 }
 public EuclideanDistanceHeuristic(GraphNode destination)
 {
     this._destination = destination;
 }