public GraphSearch(SparseGraph graph, int source, int target)
        {
            _copiedNodes    = graph.NodeList;
            _edges          = graph.EdgeList;
            _target         = target;
            _source         = source;
            _targetLocation = _copiedNodes[_target].Position;
            _open           = new List <int>();
            _closed         = new List <int>();

            _open.Add(_source);
        }
Example #2
0
        public static SparseGraph FloodFill(World world, Vector2D startPosition)
        {
            var graph = new SparseGraph(false);

            var firstNode = new NavGraphNode(
                idx: graph.NextNodeIndex,
                position: startPosition
                );

            graph.AddNode(firstNode);

            FloodFill(graph: graph, world: world, node: firstNode);

            return(graph);
        }
 public AStarSearch(SparseGraph graph, int source, int target) : base(graph, source, target)
 {
 }
Example #4
0
        private static void FloodFill(SparseGraph graph, World world, NavGraphNode node)
        {
            /*
             * This method should create all edges and neighbouring nodes that are possible
             *
             * C:     Current node
             * 1 - 8: Neighbouring nodes for which the edges/nodes should be generated if not colliding with object
             * W:     Width or space between nodes
             *
             *       1 -- 2 -- 3
             *       | \  |  / |
             *       |  \ | /  |
             *       4 -- C -- 5
             *       |  / | \  |
             *       | /  |  \ |
             *       6 -- 7 -- 8
             *
             *
             *  1 (c.X - W, c.Y - W)
             *  2 (c.X    , c.Y - W)
             *  3 (c.X + W, c.Y - W)
             *  4 (c.X - W, c.Y    )
             *  5 (c.X + W, c.Y    )
             *  6 (c.X - W, c.Y + W)
             *  7 (c.X    , c.Y + W)
             *  8 (c.X + W, c.Y + W)
             */


            List <Vector2D> neighbouringPoints = new List <Vector2D>()
            {
                new Vector2D(x: node.Position.X - Width, y: node.Position.Y - Width), // 1
                new Vector2D(x: node.Position.X, y: node.Position.Y - Width),         // 2
                new Vector2D(x: node.Position.X + Width, y: node.Position.Y - Width), // 3

                new Vector2D(x: node.Position.X - Width, y: node.Position.Y),         // 4
                new Vector2D(x: node.Position.X + Width, y: node.Position.Y),         // 5

                new Vector2D(x: node.Position.X - Width, y: node.Position.Y + Width), // 6
                new Vector2D(x: node.Position.X, y: node.Position.Y + Width),         // 7
                new Vector2D(x: node.Position.X + Width, y: node.Position.Y + Width), // 8
            };

            foreach (var point in neighbouringPoints)
            {
                // Do not add node if it collides with obstacle and skip to next node
                var obstacle = IsObjectInRange(obstacles: world.Obstacles, point: point);
                if (obstacle?.Type == ItemType.Block)
                {
                    continue;
                }

                // Also skip this node if it is outside of the world boundaries
                if (point.X < 0 || point.Y < 0 || point.X > world.Width || point.Y > world.Height)
                {
                    continue;
                }

                // Try to get the neighbouring node and create a new node if it doesn't exist
                var neighbour = graph.GetNode(point.X, point.Y) ?? new NavGraphNode(graph.NextNodeIndex, point);

                // If the index is equal to the NextNodeIndex, it means that the node was created here and thus should
                // be added to the graph. If it isn't equal, we got an existing node from the graph earlier.
                var neighbourDidAlreadyExist = neighbour.Index != graph.NextNodeIndex;
                if (!neighbourDidAlreadyExist)
                {
                    graph.AddNode(neighbour);
                }

                // Check if edge exists, and add one if that is not the case
                if (!graph.EdgeList.Exists(x => x.From == node.Index && x.To == neighbour.Index))
                {
                    // But also check if the edge doesn't through an object, otherwise it shouldn't be drawn
                    var obstacleForEdge = IsObjectInRange(
                        obstacles: world.Obstacles,
                        point: new Vector2D(
                            node.Position.X +
                            ((neighbour.Position.X - node.Position.X) /
                             2), // Take the X-coordinate in the middle of the edge
                            node.Position.Y +
                            ((neighbour.Position.Y - node.Position.Y) /
                             2) // Take the Y-coordinate in the middle of the edge
                            ));

                    if (obstacleForEdge == null || obstacleForEdge?.Type != ItemType.Block)
                    {
                        // Add edge in both directions
                        graph.AddEdge(new GraphEdge(from: node.Index, to: neighbour.Index));
                        graph.AddEdge(new GraphEdge(from: neighbour.Index, to: node.Index));
                    }
                }

                // Go on with the neighbour node, if it didn't exist yet, otherwise skip to the next node
                if (neighbourDidAlreadyExist)
                {
                    continue;
                }
                FloodFill(graph: graph, world: world, node: neighbour);
            }
        }
 public DijkstraSearch(SparseGraph graph, int source, ItemType type) : base(graph, source, 0)
 {
     _requestedEntityType = type;
 }