Beispiel #1
0
        /// <summary>
        /// Uses Nearest Neighbor Simple TSP
        /// </summary>
        /// <returns></returns>
        internal static Queue <DungeonNode> GetSceneNearestNeighborRoute()
        {
            Stopwatch timer = new Stopwatch();

            timer.Start();
            Vector3 myPosition = ZetaDia.Me.Position;

            SceneSegmentation.Update();

            if (!UnVisitedNodes.Any())
            {
                return(default(Queue <DungeonNode>));
            }

            List <DungeonNode> unsortedNodes = UnVisitedNodes.ToList();
            List <DungeonNode> sortedNodes   = new List <DungeonNode>();

            var nearestNode = unsortedNodes
                              .OrderBy(node => ZetaDia.Minimap.IsExplored(node.NavigableCenter, ZetaDia.Me.WorldDynamicId))
                              .ThenBy(node => node.NavigableCenter.Distance2DSqr(myPosition))
                              .First();

            sortedNodes.Add(nearestNode);
            unsortedNodes.Remove(nearestNode);

            Dictionary <Vector2, bool> nodeExploredMap = unsortedNodes
                                                         .ToDictionary(node => node.WorldTopLeft, node => ZetaDia.Minimap.IsExplored(node.NavigableCenter, ZetaDia.Me.WorldDynamicId));

            // Enqueue closest node
            while (unsortedNodes.Any())
            {
                var nextNode = unsortedNodes
                               // Minimap Unvisited first
                               .OrderBy(n => nodeExploredMap[n.WorldTopLeft])
                               .ThenBy(n => n.Center.DistanceSqr(sortedNodes.Last().Center))
                               .First();
                sortedNodes.Add(nextNode);
                unsortedNodes.Remove(nextNode);
            }

            Queue <DungeonNode> route = new Queue <DungeonNode>(sortedNodes);

            Logger.Log("Generated new Scene Route with {0} nodes in {1}ms", route.Count, timer.ElapsedMilliseconds);
            return(route);
        }
Beispiel #2
0
        internal static Queue <DungeonNode> GetWeightedNearestMinimapUnvisitedRoute()
        {
            Stopwatch timer = new Stopwatch();

            timer.Start();
            Vector3 myPosition = ZetaDia.Me.Position;

            Queue <DungeonNode>        route         = new Queue <DungeonNode>();
            List <WeightedDungeonNode> weightedNodes = new List <WeightedDungeonNode>();

            // We want to give a high weight to nodes which have unexplored nodes near it
            // A maximum weight will be given to a node with 4 directly connected unexplored (facing) nodes, and 4 corner-connected nodes
            // This is theoretically possible if we are standing IN this maximum-weighted unexplored node
            // Typically a node will have 1 or more directly connected nodes and 0 or more corner-connected nodes

            foreach (var unWeightedNode in UnVisitedNodes)
            {
                var weightedNode = new WeightedDungeonNode(unWeightedNode.WorldTopLeft, unWeightedNode.WorldBottomRight)
                {
                    Weight = 0
                };

                // Grab unvisited nodes only, this is what we'll use for our Weighting
                int numNodesConnected = UnVisitedNodes.Count(node => node.GridCenter.DistanceSqr(weightedNode.GridCenter) <= (MaxCornerDistance * MaxCornerDistance));
                weightedNode.Weight = numNodesConnected / MaxConnectedNodes;
                weightedNodes.Add(weightedNode);
            }

            foreach (var node in weightedNodes.OrderByDescending(n => (1 / n.NavigableCenter.Distance(myPosition)) * n.Weight))
            {
                if (SetNodesExploredAutomatically && ZetaDia.Minimap.IsExplored(node.NavigableCenter, ZetaDia.CurrentWorldDynamicId))
                {
                    continue;
                }

                route.Enqueue(node);
            }

            Logger.Log("Generated new Weighted Nearest Minimap Unvisited Route with {0} nodes in {1}ms", route.Count, timer.ElapsedMilliseconds);
            return(route);
        }
Beispiel #3
0
        internal static Queue <DungeonNode> GetSceneDirectionRoute()
        {
            if (Direction == Direction.Any)
            {
                Logger.Log("No Direction selected for Scene Route - using Scene TSP");
                return(GetSceneNearestNeighborRoute());
            }

            Stopwatch timer = new Stopwatch();

            timer.Start();
            Vector3 myPosition = ZetaDia.Me.Position;

            Queue <DungeonNode> route = new Queue <DungeonNode>();

            /*
             * North = -X
             * South = +X
             * East = +Y
             * West = -Y
             * NorthEast = -X+Y
             * NorthWest = -X-Y
             * SouthEast = +X+Y
             * SouthWest = +X-Y
             */
            switch (Direction)
            {
            case Direction.North:
                route = new Queue <DungeonNode>(UnVisitedNodes.OrderBy(node => node.GridCenter.X));
                break;

            case Direction.South:
                route = new Queue <DungeonNode>(UnVisitedNodes.OrderByDescending(node => node.GridCenter.X));
                break;

            case Direction.East:
                route = new Queue <DungeonNode>(UnVisitedNodes.OrderByDescending(node => node.GridCenter.Y));
                break;

            case Direction.West:
                route = new Queue <DungeonNode>(UnVisitedNodes.OrderBy(node => node.GridCenter.Y));
                break;

            case Direction.NorthEast:
                route = new Queue <DungeonNode>(UnVisitedNodes.OrderBy(node => (node.GridCenter.X - node.GridCenter.Y)));
                break;

            case Direction.NorthWest:
                route = new Queue <DungeonNode>(UnVisitedNodes.OrderBy(node => (node.GridCenter.X + node.GridCenter.Y)));
                break;

            case Direction.SouthEast:
                route = new Queue <DungeonNode>(UnVisitedNodes.OrderByDescending(node => (node.GridCenter.X + node.GridCenter.Y)));
                break;

            case Direction.SouthWest:
                route = new Queue <DungeonNode>(UnVisitedNodes.OrderByDescending(node => (node.GridCenter.X - node.GridCenter.Y)));
                break;
            }

            Logger.Log("Generated new Scene Direction Route with {0} nodes in {1}ms", route.Count, timer.ElapsedMilliseconds);
            return(route);
        }