/// <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; } } } }
/// <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; } } } }
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; } }