Exemplo n.º 1
0
        private TradeMapSystemCollection GetSystemsInJumpRange(TradeMap map, TradeMapSystem startSystem, TradeMapSystemCollection systemCollection, int jumpRange)
        {
            // Traverse outwards from the start system using links.
            // Build a collection of systems within the specified jump radius from the start system

            TradeMapSystemCollection seenSystems = new TradeMapSystemCollection();

            if (!systemCollection.Contains(startSystem))
            {
                systemCollection.Add(startSystem);
            }
            Stack <TradeMapSystem> systemStack = new Stack <TradeMapSystem>();

            systemStack.Push(startSystem);
            Stack <TradeMapSystem> nextSystemStack;

            int jumpCount = 1;

            while (jumpCount <= jumpRange && systemStack.Count > 0)
            {
                // Start the next stack
                nextSystemStack = new Stack <TradeMapSystem>();

                // Add all of the linked systems
                while (systemStack.Count > 0)
                {
                    var thisSystem = systemStack.Pop();
                    if (seenSystems.Contains(thisSystem))
                    {
                        continue;
                    }

                    foreach (var link in thisSystem.Links)
                    {
                        if (link.System == null)
                        {
                            continue;
                        }
                        if (link.System == startSystem)
                        {
                            continue;                             // Ignore it if it's start system
                        }
                        // Good link
                        nextSystemStack.Push(link.System);
                        if (!systemCollection.Contains(link.System))
                        {
                            systemCollection.Add(link.System);
                        }
                        seenSystems.Add(thisSystem);
                    }
                }

                // Done with stack, ready the next stack
                systemStack = nextSystemStack;

                jumpCount++;
            }

            return(systemCollection);
        }
Exemplo n.º 2
0
        public RouteScannerResults Scan(TradeMap map, RouteScannerOptions options, CancellationToken ct)
        {
            if (_working)
            {
                throw new InvalidOperationException("Already working");
            }
            _working = true;
            _log.Info("Starting route scan");

            _ct = ct;

            _options = options;

            var r = new RouteScannerResults();

            // Build a list of profitable runs
            // Loop through systems
            // Get list of systems within the max jump limit
            // Go through each system in the list, compare comodity prices
            // If the price is greater than the desired threshold, add it to the run list

            TradeMapSystemCollection systemCollection;
            List <string>            validMapBoundSystems = new List <string>();

            if (options.MapBounds.Count > 0)
            {
                // Gather map bounds
                systemCollection = new TradeMapSystemCollection();
                foreach (var system in map.Systems)
                {
                    foreach (var mapBound in options.MapBounds)
                    {
                        var mapBoundSystem = mapBound.Key.ToLower();
                        if (mapBoundSystem == system.Name.ToLower())
                        {
                            validMapBoundSystems.Add(mapBoundSystem);
                            GetSystemsInJumpRange(map, system, systemCollection, mapBound.Value);
                            continue;
                        }
                    }
                }

                // Validate
                foreach (var mapBound in options.MapBounds)
                {
                    if (!validMapBoundSystems.Contains(mapBound.Key.ToLower()))
                    {
                        throw new IndexOutOfRangeException($"Map bound system name isn't a known system '{mapBound.Key}'");
                    }
                }
            }
            else
            {
                // Do for all systems
                systemCollection = map.Systems;
            }


            for (var iSS = 0; iSS < systemCollection.Count; iSS++)
            {
                ct.ThrowIfCancellationRequested();

                var startSystem = systemCollection[iSS];

                if (!startSystem.CanTrade)
                {
                    continue;                        // Don't care about system's that can't trade.
                }
                _log.Debug($"Scanning runs for system: {startSystem.Name}");
                DoProgress(new ProgressEventArgs(iSS, map.Systems.Count, ProgressEventStatus.Working, $"Scanning runs for '{startSystem.Name}' ({iSS+1}/{systemCollection.Count})"));

                // Clear this system's runs, in case
                startSystem.Runs.Clear();
                List <TradeMapSystem>  seenSystems      = new List <TradeMapSystem>();
                List <TradeMapSystem>  systemsInRange   = new List <TradeMapSystem>();
                Stack <TradeMapSystem> systemCheckStack = new Stack <TradeMapSystem>();
                Stack <TradeMapSystem> systemCheckStackNext;

                // Add this system's links to the "to do" stack
                foreach (var link in startSystem.Links)
                {
                    ct.ThrowIfCancellationRequested();
                    if (link.System == null)
                    {
                        continue;
                    }
                    if (link.System == startSystem)
                    {
                        continue;                             // Ignore it if it's start system
                    }
                    systemsInRange.Add(link.System);
                    systemCheckStack.Push(link.System);
                }

                for (int jumpCount = 1; jumpCount <= options.RunMaxJumps; jumpCount++)
                {
                    ct.ThrowIfCancellationRequested();
                    systemCheckStackNext = new Stack <TradeMapSystem>(); // Ready to compile the next list of jumps

                    // Find new systems in the check stack
                    while (systemCheckStack.Count > 0)
                    {
                        ct.ThrowIfCancellationRequested();
                        var destSystem = systemCheckStack.Pop();

                        // Check for profitable runs to this system
                        if (destSystem.CanTrade) // Avoid systems that have comodity data, but can't actually trade
                        {
                            ScanForRuns(startSystem, destSystem, jumpCount, r.AllRuns, options);
                        }

                        // Check for jumps away from this system
                        // but only if we're under the jump limit
                        if (jumpCount < options.RunMaxJumps)
                        {
                            //_log.Debug($"{jumpCount} under jump limit {options.RunMaxJumps}, looking for more destinations");
                            foreach (var link in destSystem.Links)
                            {
                                if (link.System == null)
                                {
                                    continue;
                                }
                                if (link.System == startSystem)
                                {
                                    continue;                             // Ignore it if it's start system
                                }
                                if (seenSystems.Contains(link.System))
                                {
                                    continue;
                                }

                                // New system
                                //_log.Debug($"Enquing system '{link.System.Name}'");
                                seenSystems.Add(link.System);
                                systemsInRange.Add(link.System);
                                systemCheckStackNext.Push(link.System);
                            }
                        }
                        else
                        {
                            //_log.Debug($"Hit jump limit, not going further");
                        }
                    }

                    // Make the next stack the current stack
                    systemCheckStack = systemCheckStackNext;
                }
            }

            // Scan for routes
            _log.Info("Starting scan for routes");

            TradeMapSystemCollection systemsToRoute;

            if (options.StartSystems.Count == 0)
            {
                // No systems specified, do them all
                systemsToRoute = systemCollection;
            }
            else
            {
                // Systems are specified.
                // Resolve them to systems
                systemsToRoute = new TradeMapSystemCollection();
                foreach (var system in map.Systems)
                {
                    if (options.StartSystems.Contains(system.Name.ToLower()))
                    {
                        systemsToRoute.Add(system);
                    }
                }
            }

            for (var iSS = 0; iSS < systemsToRoute.Count; iSS++)
            {
                ct.ThrowIfCancellationRequested();
                var startSystem = systemsToRoute[iSS];

                DoProgress(new ProgressEventArgs(iSS, systemsToRoute.Count, ProgressEventStatus.Working, $"Scanning routes for '{startSystem.Name}' ({iSS+1}/{systemsToRoute.Count})"));
                ScanForRoutes(startSystem, r.AllRoutes, options);
            }

            //DoProgress(new ProgressEventArgs(ProgressEventStatus.Complete, $"Route scanning complete"));
            _working = false;
            return(r);
        }