/// <summary>
        /// Finds the best delivery task for the specified pod.
        /// Sets <code>bestDeliveryRequest</code> to null if none found, otherwise <code>bestDeliveryRequest</code> and <code>bestTimeForDeliveryRequest</code> are initialized.
        /// </summary>
        /// <param name="bot">The bot to consider.</param>
        /// <param name="pod">Pod to take.</param>
        /// <param name="podLocation">Current location of the pod.</param>
        /// <param name="bestExtractTask">The best extract task set by this method.</param>
        /// <param name="bestTimeForExtract">The time of the best extract set by this method.</param>
        void GetBestTaskForPod(Bot bot, Pod pod, Waypoint podLocation,
                               out ExtractRequest bestExtractTask, out double bestTimeForExtract)
        {
            bestExtractTask    = null;
            bestTimeForExtract = 0.0;

            bestExtractTask = null;
            if (pod == null || podLocation == null)
            {
                return;
            }

            bestTimeForExtract = double.PositiveInfinity;

            // Check all tasks
            foreach (var delivery in Instance.ResourceManager.AvailableAndAssignedExtractRequests)
            {
                // If it has the item
                if (pod.IsContained(delivery.Item))
                {
                    // See how long it would take to get to the output-station
                    // Choose the worst of delivering or waiting
                    Waypoint sw   = delivery.Station.Waypoint;
                    double   time = Math.Max(Estimators.EstimateTravelTimeEuclid(bot, podLocation, sw), Estimators.EstimateOutputStationWaitTime(bot, sw));

                    // If it's the best, then use it
                    if (time < bestTimeForExtract)
                    {
                        bestExtractTask    = delivery;
                        bestTimeForExtract = time;
                    }
                }
            }
        }
Exemple #2
0
        /// <summary>
        /// Finds the best delivery task for the specified pod.
        /// Sets <code>bestDeliveryRequest</code> to null if none found, otherwise <code>bestDeliveryRequest</code> and <code>bestTimeForDeliveryRequest</code> are initialized.
        /// </summary>
        /// <param name="bot">The bot to consider.</param>
        /// <param name="pod">Pod to take.</param>
        /// <param name="podLocation">Current location of the pod.</param>
        /// <param name="bestExtractTask">The best extract task set by this method.</param>
        /// <param name="bestDistanceForExtract">The distance of the best extract set by this method.</param>
        void GetBestTaskForPod(Bot bot, Pod pod, Waypoint podLocation,
                               out ExtractRequest bestExtractTask, out double bestDistanceForExtract)
        {
            bestExtractTask        = null;
            bestDistanceForExtract = 0.0;

            bestExtractTask = null;
            if (pod == null || podLocation == null)
            {
                return;
            }

            bestDistanceForExtract = double.PositiveInfinity;

            // Check all tasks
            foreach (var delivery in Instance.ResourceManager.AvailableAndAssignedExtractRequests)
            {
                // If it has the item
                if (pod.IsContained(delivery.Item))
                {
                    // See how long it would take to get to the output-station
                    // Choose the worst of delivering or waiting
                    Waypoint sw = delivery.Station.Waypoint; // fixed per item
                                                             //double distance = Math.Max(Estimators.EstimateTravelTimeEuclid(bot, podLocation, sw), Estimators.EstimateOutputStationWaitTime(bot, sw));
                    double distance = (bot.GetDistance(sw) + ((bot.Tier == sw.Tier) ? 0 : bot.Instance.WrongTierPenaltyDistance));
                    //double waitDistance = ((ws.ItemTransferTime + 5 * 2 * bot.Radius) / bot.MaxVelocity) * w.BotCountOverall * w.BotCountOverall; // TODO this time estimate cannot hold when transferring multiple items at once

                    // If it's the best, then use it
                    if (distance < bestDistanceForExtract)
                    {
                        bestExtractTask        = delivery;
                        bestDistanceForExtract = distance;
                    }
                }
            }
        }
Exemple #3
0
        private bool DoExtractTaskWithPod(Bot bot, Pod pod)
        {
            bestExtractTask         = null;
            bestTimestampForExtract = 0.0;


            foreach (var delivery in Instance.ResourceManager.AvailableAndAssignedExtractRequests)
            {
                // If it has the item
                if (pod.IsContained(delivery.Item))
                {
                    timestamp = delivery.Order.Timestamp
                                // If it's the best, then use it
                                if (timestamp < bestTimestampForExtract)
                    {
                        bestExtractTask         = delivery;
                        bestTimestampForExtract = timestamp;
                    }
                }
            }



            // Bring items to the randomly selected first fitting station
//             foreach (var oStation in Instance.OutputStations.OrderBy(s => GetOrderValue(s, bot)))
//             {
//                 // Search for requests matching the items of the pod
//                 List<ExtractRequest> fittingRequests = GetPossibleRequests(pod, oStation, PodSelectionExtractRequestFilteringMode.AssignedOnly);
//                 if (fittingRequests.Any())
//                 {
//                     ExtractRequest oldestRequest = fittingRequests.OrderBy(o => o.Order.TimeStamp).First();
//                     // Simply execute the next task with the pod
//                     EnqueueExtract(
//                         bot, // The bot itself
//                         oStation, // The random station
//                         pod, // Keep the pod
//                         new List<ExtractRequest> { oldestRequest }); // The first requests to serve

//                     // Finished search for next task
//                     return true;
//                 }
//             }
            if (bestExtractTask != Null)
            {
                // Simply execute the next task with the pod
                EnqueueExtract(
                    bot,      // The bot itself
                    oStation, // The random station
                    pod,      // Keep the pod
                    new List <ExtractRequest> {
                    oldestRequest
                });                                              // The first requests to serve

                // Finished search for next task
                return(true);
            }
            else
            {
                // No fitting request
                return(false);
            }
        }
        private void ItemExtracted(Pod pod, ItemDescription item)
        {
            // Skip callback, if inactive
            if (!_instance.SettingConfig.MonitorWellSortedness)
            {
                return;
            }
            // Return if not in use yet
            if (_podsContainingItems == null)
            {
                return;
            }
            // --> Update pod utility
            int  itemDemand       = _instance.StockInfo.GetCurrentDemand(item);
            bool updateUtilityMax = false;

            // Update demand by new content of pod (pod lost one of these items)
            if (itemDemand >= pod.CountContained(item))
            {
                // The demand for this item is still high, but we can now supply one item less (because the content is low in comparison to the demand)
                _podUtility[pod]--;
                // Check whether utility max has to be updated
                if (pod == _podUtilityMaxPod)
                {
                    updateUtilityMax = true;
                }
            }
            // Update to new demand (demand for the given item sunk by one)
            foreach (var itemPod in _podsContainingItems[item])
            {
                // If the demand for the item is less then the pod content, we need to update to the new demand by decreasing the utility by one
                if (itemDemand < itemPod.CountContained(item))
                {
                    _podUtility[itemPod]--;
                    // Check whether utility max has to be updated
                    if (itemPod == _podUtilityMaxPod)
                    {
                        updateUtilityMax = true;
                    }
                }
            }
            // Refresh new max
            if (updateUtilityMax)
            {
                VolatileKeyValuePair <Pod, double> bestUtility = _podUtility.ArgMax(pu => pu.Value);
                _podUtilityMaxPod = bestUtility.Key;
                PodUtilityMax     = bestUtility.Value;
            }
            // --> Remove pod from list of pods containing / offering the item, if it was the last one
            if (!pod.IsAvailable(item))
            {
                _podsAvailableItems[item].Remove(pod);
            }
            if (!pod.IsContained(item))
            {
                _podsContainingItems[item].Remove(pod);
            }
            // --> Update pod speed
            _podSpeed[pod] -= _instance.FrequencyTracker.GetStaticFrequency(item);
            if (pod == _podSpeedMaxPod)
            {
                // Refresh max value
                VolatileKeyValuePair <Pod, double> bestSpeed = _podSpeed.ArgMax(ps => ps.Value);
                _podSpeedMaxPod = bestSpeed.Key;
                PodSpeedMax     = bestSpeed.Value;
            }
        }