예제 #1
0
 public PathingNode(ITile tile)
 {
     this.tile = tile;
     this.next = null;
     this.cost = 0f;
     this.order = 0f;
     this.isOpen = false;
     this.isClosed = false;
 }
예제 #2
0
        public PathingNode CalculatePath()
        {
            #region init
            if (insanityCheck > 5)
            {
                this.isEnabled = false;
                this.isActive = false;

                return null;
            }
            insanityCheck++;

            List<PathingNode> openList = new List<PathingNode>();
            List<PathingNode> nodeList = new List<PathingNode>();

            ITile originalTile = Entity.Tile;
            PathingNode originalNode = new PathingNode(originalTile);   // Starting point

            PathingNode current = new PathingNode(originalTile);
            current.cost = 0;

            ITile endTile = this.Destination;

            if (endTile == originalTile)
                return current;
            if (endTile == null)
                return current;
            if (endTile is NullTile)
                return current;
            #endregion

            openList.Add(current);

            while (openList.Count > 0)
            {
                current = openList.OrderBy(x => x.cost).First();    // first iteration, only item in openList is the original tile
                openList.Remove(current);                           // first iteration, this is now an empty list
                current.isClosed = true;                            // first iteration, only node is now closed
                current.isOpen = false;                             // first iteration, only node is now not open

                foreach (ITile tile in current.neighbors)           // first iteration, these are the tiles directly adjacent to the entity
                {
                    PathingNode node = AnalyzeNode(tile, current, originalTile, // first iteration, current is the starting position, tile is an adjacent position - current.tile == originalTile
                        endTile, openList, nodeList);               // first iteration, openList and nodeList are empty at this point

                    if (node != null)
                        return node;                        // node.next.tile is the endTile, originalNode.next should be the first tile
                }
            }

            return current;
        }
예제 #3
0
        private List<PathingNode> BuildPath(PathingNode node)
        {
            List<PathingNode> tempList = new List<PathingNode>();
            PathingNode original = node;

            int order = 0;

            if (node != null)
            {
                order = 1000;                              // since the original node is the 2nd to last one, we are reversing the order - so count down

                node.order = order;
                tempList.Add(node);

                while (node.next != null)
                {
                    order -= 1;             // noep // since the original node is the 2nd to last one, we are reversing the order - so count down

                    node = node.next;       // get next node and store this order number
                    node.order = order;

                    tempList.Add(node);     // save in list
                }
            }

            if (tempList.Count > 0)
            {
                if (tempList.OrderBy(x => x.order).First().tile != this.Entity.Tile)
                    throw new ArgumentException("Bad list, lowest 'order' should be current location");
                else
                    tempList.Remove(tempList.OrderBy(x => x.order).First());
            }

            return tempList;                // the original node should have order == 1000, with the path going backwards - lowest number should be the entity's current location
        }
예제 #4
0
        private PathingNode AnalyzeNode(ITile tile, PathingNode current, ITile originalTile, ITile endTile, 
            List<PathingNode> openList, List<PathingNode> nodeList)
        {
            PathingNode node;   // node is one of current's neighbors

            if (tile != null && tile != originalTile)
            {
                if (tile.IsBlocked == false
                    //|| tile == endTile
                    )
                {
                    // node is one of current's neighbors
                    node = nodeList.Where(x => x.tile == tile).SingleOrDefault();

                    if (node == null)
                    {   // if this is the first time ecountering this tile...
                        node = new PathingNode(tile);   // wrap the tile reference in a Node
                        nodeList.Add(node);
                    }

                    if (node.isClosed == false)
                    {
                        #region calculate cost
                        float cost = 0;             // higher this is, the worse of a 'guess' it is - it should get smaller as the tiles get closer to the destination

                        // straight line
                        cost += Vector2.Distance(current.tile.Position, endTile.Position);

                        cost += current.cost;       // not 100% sure on the logic of this one...
                        #endregion

                        if (cost < node.cost        // if the cost just calculated is less than what the node presently has, that means this current node is 'closer' than the selected node
                            || node.cost == 0       // if node.cost is 0, then any other position is a valid guess
                            )
                        {
                            node.cost = cost;       // this is the cost of the new 'next' node (best guess so far),
                            node.next = current;    // first.next -> original, second.next -> first, third.next -> second, etc
                        }

                        if (node.isOpen == false)
                        {
                            if (node.tile == endTile)
                            {
                                node.next = current;    // node.next is the final location
                                return node;            // this is the last node --> goes to BuildPath to assign 'order' values
                            }

                            node.isOpen = true;
                            openList.Add(node);
                        }
                    }
                }
            }

            return null;
        }