/// <summary> /// Chooses a rest location from all available ones for the given bot. /// </summary> /// <param name="bot">The bot to choose a rest location for.</param> /// <param name="restLocationOrderType">The rest location preference.</param> private Waypoint ChooseRestLocation(Bot bot, PrefRestLocationForBot restLocationOrderType) { return (Instance.ResourceManager.UnusedRestingLocations.Any() ? // Check whether there is another free pod storage location to use for resting Instance.ResourceManager.UnusedRestingLocations.ArgMin(w => RestLocationToBotAllocationMetric(restLocationOrderType, bot, w)) : Instance.WaypointGraph.GetClosestWaypoint(bot.Tier, bot.X, bot.Y));; }
/// <summary> /// Attempts to do a repositioning task. If no such task is available a resting task is done instead. /// </summary> /// <param name="bot">The bot.</param> /// <param name="restLocationOrder">The order in which the next free resting location is chosen.</param> /// <returns><code>true</code> if a repositioning move was found, <code>false</code> otherwise.</returns> protected bool DoRepositioningTaskOrRest(Bot bot, PrefRestLocationForBot restLocationOrder) { // Reposition a pod, if a move is available RepositioningMove move = Instance.Controller.RepositioningManager.GetNextMove(bot); // Check whether a suitable move was available if (move != null) { // We found a repositioning move - skip resting and proceed with repositioning instead EnqueueRepositionPod(bot, move.Pod, move.StorageLocation); return(true); } // No repositioning move - just rest DoRestTask(bot, restLocationOrder); return(false); }
/// <summary> /// Allocates a rest task. /// </summary> /// <param name="bot">The bot that shall rest.</param> /// <param name="restLocationOrder">The order in which the next free resting location is chosen (if the bot already rested before, the same location is used).</param> protected void DoRestTask(Bot bot, PrefRestLocationForBot restLocationOrder) { // Get the last task that was assigned to the bot BotTask lastTask = GetLastEnqueuedTask(bot); // Choose resting location Waypoint restLocation; // Check whether the last task was resting too if (lastTask != null && lastTask.Type == BotTaskType.Rest && Instance.ResourceManager.IsRestingLocationAvailable((lastTask as RestTask).RestingLocation)) { restLocation = (lastTask as RestTask).RestingLocation; } else { restLocation = ChooseRestLocation(bot, restLocationOrder); } // Submit the task EnqueueRest(bot, restLocation); }
/// <summary> /// Determines a value that can be used to order possible rest locations for a pod. /// </summary> /// <param name="orderType">The order metric to use.</param> /// <param name="bot">The bot looking for a job.</param> /// <param name="restLocation">The rest location to look at.</param> /// <returns>A value reflecting the given metric. The lowest value indicates the best option for the given metric.</returns> public double RestLocationToBotAllocationMetric(PrefRestLocationForBot orderType, Bot bot, Waypoint restLocation) { double value; switch (orderType) { case PrefRestLocationForBot.Random: value = Instance.Randomizer.NextDouble(); break; case PrefRestLocationForBot.RandomSameTier: value = restLocation.Tier == bot.Tier ? -Instance.Randomizer.NextDouble() : Instance.Randomizer.NextDouble(); break; case PrefRestLocationForBot.Middle: value = bot.GetDistance(bot.Tier.Length / 2.0, bot.Tier.Width / 2.0); break; case PrefRestLocationForBot.MiddleSameTier: value = restLocation.Tier == bot.Tier ? restLocation.GetDistance(restLocation.Tier.Length / 2.0, restLocation.Tier.Width / 2.0) : restLocation.GetDistance(restLocation.Tier.Length / 2.0, restLocation.Tier.Width / 2.0) + Instance.WrongTierPenaltyDistance;; break; case PrefRestLocationForBot.Nearest: value = restLocation.Tier == bot.Tier ? bot.GetDistance(restLocation) : bot.GetDistance(restLocation) + Instance.WrongTierPenaltyDistance; break; default: throw new ArgumentException("Unknown order type: " + orderType); } return(value); }