/// <summary> /// Prepare additional unit training plans by selecting the cheapest units /// taking into account the budget and the existing training plan, if any /// </summary> /// <param name="province">The province for which to prepare unit training plans</param> /// <param name="budget">The amount of money available for spending</param> /// <param name="existingPlan">The province's current training plan</param> /// <returns>List of unit training plans</returns> private List <UnitTrainingPlan> PlanTrainingFodder(Province province, int budget, ProvinceTrainingPlan existingPlan = null) { List <UnitTrainingPlan> result = new List <UnitTrainingPlan>(); int manpower = province.GetRemainingManpower(); if (existingPlan != null) { manpower -= existingPlan.GetManpowerCost(); } // no recruits or no money => good buy! if (manpower <= 0 || budget <= 0) { return(result); } List <UnitType> trainable = province.GetCheapestToTrainUnits(); Dictionary <UnitType, int> trainingOrder = new Dictionary <UnitType, int>(); if (trainable.Count > 0) { if (trainable.Count == 1) { // simple - train this single cheapest unit trainingOrder[trainable[0]] = Mathf.Min(manpower, budget / trainable[0].GetTrainingCost()); } else { // more complicated - select one of the options randomly for (int i = 0; i < trainable.Count; i++) { trainingOrder[trainable[i]] = 0; } for (int i = 0; i < manpower; i++) { int randomIndex = UnityEngine.Random.Range(0, trainable.Count); trainingOrder[trainable[randomIndex]] += 1; budget -= trainable[randomIndex].GetTrainingCost(); if (budget <= 0) { break; } } } } foreach (KeyValuePair <UnitType, int> entry in trainingOrder) { if (entry.Value > 0) { UnitTrainingOrder order = new UnitTrainingOrder(entry.Key, entry.Value, false); result.Add(new UnitTrainingPlan(order, UnitTrainingPlan.Reason.FODDER)); } } return(result); }
/// <summary> /// Prepare unit training plans by selecting the cheapest units /// </summary> /// <param name="province">The province for which to prepare unit training plans</param> /// <returns>Dictionary of unit type => number of units to train</returns> private Dictionary <UnitType, int> FillTrainingOrderWithCheapestUnits(Province province) { // NOTE: take into account that a faction may not have enough money to train even // the cheapest units up to the province's manpower level Dictionary <UnitType, int> trainingOrder = new Dictionary <UnitType, int>(); List <UnitType> chaff = province.GetCheapestToTrainUnits(); if (chaff.Count > 0) { if (chaff.Count == 1) { // simple - train this single cheapest unit trainingOrder[chaff[0]] = Mathf.Min(province.GetManpower(), province.GetOwnersFaction().GetMoneyBalance() / chaff[0].GetTrainingCost()); } else { int availableIncome = province.GetOwnersFaction().GetMoneyBalance(); // more complicated - select one of the options randomly for (int i = 0; i < chaff.Count; i++) { trainingOrder[chaff[i]] = 0; } for (int i = 0; i < province.GetManpower(); i++) { int randomIndex = UnityEngine.Random.Range(0, chaff.Count); trainingOrder[chaff[randomIndex]] += 1; availableIncome -= chaff[randomIndex].GetTrainingCost(); if (availableIncome <= 0) { break; } } } } return(trainingOrder); }
/// <summary> /// Revise training plans of the cheapest units based on the money left and the existing training plan, if available /// </summary> /// <param name="province">The province for which to prepare unit training plans</param> /// <param name="budget">The amount of money available for spending</param> /// <param name="existingPlan">The province's current training plan</param> private void UpgradeTrainingFodderPlan(Province province, int budget, ProvinceTrainingPlan existingPlan) { // no money => good buy! if (budget <= 0) { return; } List <UnitType> trainable = province.GetTrainableUnits(); Dictionary <UnitType, int> trainingOrder = new Dictionary <UnitType, int>(); List <UnitType> fodder = province.GetCheapestToTrainUnits(); List <UnitType> expensives = new List <UnitType>(); for (int i = 0; i < trainable.Count; i++) { if (!fodder.Contains(trainable[i])) { trainingOrder[trainable[i]] = 0; expensives.Add(trainable[i]); } } if (trainingOrder.Count > 0) { List <UnitTrainingPlan> plans = existingPlan.GetUnitTrainingPlans(); for (int i = 0; i < plans.Count; i++) { if (plans[i].GetReason() == UnitTrainingPlan.Reason.FODDER) { int manpower = plans[i].GetManpowerCost(); int fodderCost = plans[i].GetUnitTypeTrainingCost(); for (int j = 0; j < manpower; j++) { int randomIndex = UnityEngine.Random.Range(0, expensives.Count); int costIncrease = expensives[randomIndex].GetTrainingCost() - fodderCost; if (budget >= costIncrease) { trainingOrder[expensives[randomIndex]] += 1; plans[i].DecreaseQuantity(); budget -= costIncrease; } if (budget <= 0) { break; } } } if (budget <= 0) { break; } } List <UnitTrainingPlan> newPlans = new List <UnitTrainingPlan>(); foreach (KeyValuePair <UnitType, int> entry in trainingOrder) { if (entry.Value > 0) { UnitTrainingOrder order = new UnitTrainingOrder(entry.Key, entry.Value, false); newPlans.Add(new UnitTrainingPlan(order, UnitTrainingPlan.Reason.CORE)); } } if (newPlans.Count > 0) { existingPlan.AddUnitTrainingPlans(newPlans); } } return; }