Пример #1
0
        internal virtual IEnumerable <PathingNode> Neighbours(PathingNode node)
        {
            for (var i = 0; i < Directions.Length; i++)
            {
                int propX = node.Location.x + Directions[i].x;
                int propY = node.Location.y + Directions[i].y;

                if (IsNavigable(propX, propY))
                {
                    yield return(this[propX, propY]);
                }
            }
        }
Пример #2
0
        protected List <Vector2Int> Trace(PathingNode node)
        {
            var path = new List <Vector2Int> {
                node.Location
            };

            while (node.Parent != null)
            {
                node = node.Parent;
                path.Add(node.Location);
            }
            path.Reverse();
            return(path);
        }
Пример #3
0
        private void IdentitySuccessors(PathingNode node)
        {
            foreach (PathingNode neighbour in _graph.Neighbours(node))
            {
                System.DateTime s         = System.DateTime.Now;
                Vector2Int      jumpPoint = Jump(neighbour.Location, node.Location);
                JumpCostTime += ((System.DateTime.Now - s).TotalMilliseconds);

                if (jumpPoint != Utils.InvalidGrid)
                {
                    PathingNode jumpNode = _graph[jumpPoint];

                    if (jumpNode.Closed)
                    {
                        continue;
                    }

                    double d  = Utils.Heuristic_Diagonal(Math.Abs(jumpPoint.x - node.Location.x), Math.Abs(jumpPoint.y - node.Location.y));
                    double ng = node.G + d;

                    if (!jumpNode.Opened || ng < jumpNode.G)
                    {
                        jumpNode.G = ng;
                        if (!jumpNode.H.HasValue)
                        {
                            jumpNode.H = Utils.Heuristic_Diagonal(Math.Abs(jumpPoint.x - _goal.x), Math.Abs(jumpPoint.y - _goal.y));
                        }
                        jumpNode.F      = jumpNode.G + jumpNode.H.Value;
                        jumpNode.Parent = node;

                        if (!jumpNode.Opened)
                        {
                            _open.Enqueue(jumpNode, jumpNode.F);
                            jumpNode.Opened = true;

                            OnNodeAddOpenSet?.Invoke(jumpNode);
                        }
                        else
                        {
                            _open.UpdatePriority(jumpNode, jumpNode.F);
                        }
                    }
                }
            }
        }
Пример #4
0
        public GridGraph(byte[,] navigable)
        {
            _boundsMinX = 0;
            _boundsMaxX = navigable.GetUpperBound(0);
            _boundsMinY = 0;
            _boundsMaxY = navigable.GetUpperBound(1);

            _navigable = navigable;

            // Initialise the Grid
            _grid = new PathingNode[_boundsMaxX + 1, _boundsMaxY + 1];
            for (var x = _boundsMinX; x <= _boundsMaxX; x++)
            {
                for (var y = _boundsMinY; y <= _boundsMaxY; y++)
                {
                    _grid[x, y] = new PathingNode(x, y);
                }
            }
        }
Пример #5
0
        public override List <Vector2Int> FindPath(Vector2Int start, Vector2Int goal)
        {
            if (_graph == null)
            {
                return(null);
            }

            _start       = start;
            _goal        = goal;
            JumpCostTime = 0;

            var startNode = new PathingNode(_start)
            {
                F = 0, G = 0, Opened = true
            };

            _open.Enqueue(startNode, startNode.F);
            this.OnNodeAddOpenSet?.Invoke(startNode);

            while (_open.Count != 0)
            {
                PathingNode node = _open.Dequeue();

                node.Closed = true;
                this.OnNodeVisited?.Invoke(node);

                if (node.Location == _goal)
                {
                    return(Trace(node));
                }

                IdentitySuccessors(node);
            }

            return(null);
        }
Пример #6
0
        internal override IEnumerable <PathingNode> Neighbours(PathingNode node)
        {
            if (node.Parent != null)
            {
                Vector2Int n = node.Location;
                Vector2Int p = node.Parent.Location;

                Vector2Int dNorm = new Vector2Int(
                    (n.x - p.x) / Math.Max(Math.Abs(n.x - p.x), 1),
                    (n.y - p.y) / Math.Max(Math.Abs(n.y - p.y), 1));

                // Diagonal
                if (dNorm.x != 0 && dNorm.y != 0)
                {
                    if (IsNavigable(n.x, n.y + dNorm.y))
                    {
                        yield return(_grid[n.x, n.y + dNorm.y]);
                    }

                    if (IsNavigable(n.x + dNorm.x, n.y))
                    {
                        yield return(_grid[n.x + dNorm.x, n.y]);
                    }

                    if ((IsNavigable(n.x, n.y + dNorm.y) || IsNavigable(n.x + dNorm.x, n.y)) && IsNavigable(n.x + dNorm.x, n.y + dNorm.y))
                    {
                        yield return(_grid[n.x + dNorm.x, n.y + dNorm.y]);
                    }

                    if (!IsNavigable(n.x - dNorm.x, n.y) && IsNavigable(n.x, n.y + dNorm.y) && IsNavigable(n.x - dNorm.x, n.y + dNorm.y))
                    {
                        yield return(_grid[n.x - dNorm.x, n.y + dNorm.y]);
                    }

                    if (!IsNavigable(n.x, n.y - dNorm.y) && IsNavigable(n.x + dNorm.x, n.y) && IsNavigable(n.x + dNorm.x, n.y - dNorm.y))
                    {
                        yield return(_grid[n.x + dNorm.x, n.y - dNorm.y]);
                    }
                }
                // Cardinal
                else
                {
                    if (dNorm.x == 0)
                    {
                        if (IsNavigable(n.x, n.y + dNorm.y))
                        {
                            yield return(_grid[n.x, n.y + dNorm.y]);

                            if (!IsNavigable(n.x + 1, n.y) && IsNavigable(n.x + 1, n.y + dNorm.y))
                            {
                                yield return(_grid[n.x + 1, n.y + dNorm.y]);
                            }

                            if (!IsNavigable(n.x - 1, n.y) && IsNavigable(n.x - 1, n.y + dNorm.y))
                            {
                                yield return(_grid[n.x - 1, n.y + dNorm.y]);
                            }
                        }
                    }
                    else if (IsNavigable(n.x + dNorm.x, n.y))
                    {
                        yield return(_grid[n.x + dNorm.x, n.y]);

                        if (!IsNavigable(n.x, n.y + 1) && IsNavigable(n.x + dNorm.x, n.y + 1))
                        {
                            yield return(_grid[n.x + dNorm.x, n.y + 1]);
                        }

                        if (!IsNavigable(n.x, n.y - 1) && IsNavigable(n.x + dNorm.x, n.y - 1))
                        {
                            yield return(_grid[n.x + dNorm.x, n.y - 1]);
                        }
                    }
                }
            }
            else
            {
                for (var i = 0; i < Directions.Length; i++)
                {
                    int propX = node.Location.x + Directions[i].x;
                    int propY = node.Location.y + Directions[i].y;

                    if (IsNavigable(propX, propY))
                    {
                        yield return(this[propX, propY]);
                    }
                }
            }
        }
Пример #7
0
        public override List <Vector2Int> FindPath(Vector2Int start, Vector2Int goal)
        {
            if (_graph == null)
            {
                return(null);
            }

            _start = start;
            _goal  = goal;

            var startNode = new PathingNode(_start)
            {
                F = 0, G = 0, Opened = true
            };

            _open.Enqueue(startNode, startNode.F);
            this.OnNodeAddOpenSet?.Invoke(startNode);

            while (_open.Count != 0)
            {
                PathingNode curNode = _open.Dequeue();
                curNode.Closed = true;
                this.OnNodeVisited?.Invoke(curNode);

                if (curNode.Location == _goal)
                {
                    return(Trace(curNode));
                }

                foreach (var neighbour in  _graph.Neighbours(curNode))
                {
                    if (neighbour.Closed)
                    {
                        continue;
                    }

                    double d = Utils.Heuristic_Diagonal(Math.Abs(neighbour.Location.x - curNode.Location.x),
                                                        Math.Abs(neighbour.Location.y - curNode.Location.y));
                    double ng = curNode.G + d;

                    if (!neighbour.Opened || ng < neighbour.G)
                    {
                        neighbour.G = ng;
                        if (!neighbour.H.HasValue)
                        {
                            neighbour.H = Utils.Heuristic_Diagonal(Math.Abs(neighbour.Location.x - _goal.x),
                                                                   Math.Abs(neighbour.Location.y - _goal.y));
                        }
                        neighbour.F      = (neighbour.G + neighbour.H.Value);
                        neighbour.Parent = curNode;

                        if (!neighbour.Opened)
                        {
                            _open.Enqueue(neighbour, neighbour.F);
                            neighbour.Opened = true;

                            OnNodeAddOpenSet?.Invoke(neighbour);
                        }
                        else
                        {
                            _open.UpdatePriority(neighbour, neighbour.F);
                        }
                    }
                }
            }

            return(null);
        }