private void PerformUnfocusedDistribution(int workerCount, IEnumerable <IWorkerSlot> slots, ICity sourceCity) { var maximizingComparison = SlotComparisonUtil.BuildTotalYieldComparisonAscending(sourceCity, GenerationLogic); MaximizeYield(workerCount, slots, sourceCity, maximizingComparison); MitigateStarvation(workerCount, slots, sourceCity, maximizingComparison); }
private void MitigateStarvation(int workerCount, IEnumerable <IWorkerSlot> slots, ICity sourceCity, Comparison <IWorkerSlot> yieldMaximizationComparer) { int foodProduced = Mathf.FloorToInt(GenerationLogic.GetTotalYieldForCity(sourceCity)[YieldType.Food]); int foodRequired = GrowthLogic.GetFoodConsumptionPerTurn(sourceCity); var occupiedByMaxYieldDescending = new List <IWorkerSlot>(slots.Where(slot => slot.IsOccupied)); occupiedByMaxYieldDescending.Sort(yieldMaximizationComparer); occupiedByMaxYieldDescending.Reverse(); var slotsByFoodThenFocusedYield = new List <IWorkerSlot>(slots); var foodComparer = SlotComparisonUtil.BuildYieldComparisonAscending(YieldType.Food, sourceCity, GenerationLogic); slotsByFoodThenFocusedYield.Sort(delegate(IWorkerSlot firstSlot, IWorkerSlot secondSlot) { int foodComparison = foodComparer(firstSlot, secondSlot); return(foodComparison != 0 ? foodComparison : yieldMaximizationComparer(firstSlot, secondSlot)); }); while (foodProduced < foodRequired) { var worstOccupiedForFocus = occupiedByMaxYieldDescending.LastOrDefault(); var bestUnoccupiedForFood = slotsByFoodThenFocusedYield.LastOrDefault(slot => !slot.IsOccupied); if (worstOccupiedForFocus != null && bestUnoccupiedForFood != null) { worstOccupiedForFocus.IsOccupied = false; bestUnoccupiedForFood.IsOccupied = true; occupiedByMaxYieldDescending.Remove(worstOccupiedForFocus); slotsByFoodThenFocusedYield.Remove(bestUnoccupiedForFood); foodProduced = Mathf.FloorToInt(GenerationLogic.GetTotalYieldForCity(sourceCity)[YieldType.Food]); } else { break; } } }