@VisibleForTesting int calculateBuyAmount(IWare ware, ICity city, IAIPlayer player, ETradeReason tradeReason, List<IWorkShop> workShops) { switch (tradeReason) { case REQUIRE_FOR_PRODUCTION: // one week supply return workShops.stream() .filter(workshop -> productionChain.getRequiredWares(workshop.getProducableWare()).contains(ware)) .mapToInt(workshop -> (int)Math.ceil(productionChain.getRequiredAmount(workshop.getProducableWare(), ware))) .sum(); case PRODUCED_WARE_IN_CITY: // if needed in city or city is central storage, buy higher amount int baseAmount; if (ware.isBarrelSizedWare()) { baseAmount = 20; } else { baseAmount = 5; } if (tradeService.getBasicNeeds().contains(ware) || hasCentralStorageStrategy(city, player)) { baseAmount *= 2; } return baseAmount; default: throw new IllegalStateException("Unhandled buy trade reason: "+tradeReason); } }
int amountWorkshops = population / populationAmountPerWorkshop + 1; double theoreticalProducableAmount = productionChain.getProduction(ware) * amountWorkshops * adjustmentFactor; List<IWare> requiredWares = productionChain.getRequiredWares(ware); if (requiredWares.isEmpty()) { return theoreticalProducableAmount; // Now raw material needed the whole amount can be produced double minProducableAmount = theoreticalProducableAmount; for (IWare requiredWare : requiredWares) { double requiredAmount = productionChain.getRequiredAmount(ware, requiredWare) * amountWorkshops * adjustmentFactor; double storedAmount = storage.getStored(requiredWare); if (storedAmount >= requiredAmount) {
double efficientcyFactor = workshop.isProducingEfficienty() ? 1.0 : 0.5; IWare producedWare = workshop.getProducableWare(); List<IWare> required = productionChain.getRequiredWares(producedWare); ProductionStorage storage = workshop.getStorage(); double staffingFactor = workshop.getWorkers() * 1.0 / workshop.getMaxWorkers(); double requiredWareFactor = producableAmountFactor * staffingFactor; double produceWareAmount = productionChain.getProduction(producedWare) * requiredWareFactor
@Override public void initializeTradeCycle(IAIPlayer player, INavigableVessel vessel) { List<IWare> waresWithProductionChain = productionChain.getWaresWithProductionChain(); waresWithProductionChain.remove(EWare.BRICK); waresWithProductionChain.remove(EWare.PITCH); player.setTradeMission(vessel, missionData); List<IWare> requiredWares = productionChain.getRequiredWares(ware); boolean findAllHere = true; for (IWare requiredWare : requiredWares) {
/** * Calculate the maximal factor for a ware that can be produced based on avalable material. * @param storage from which to take the required ware * @param requiredWare that's availability is to be checked * @param producableWare output product * @return factor that has to be applied to the maximal producable amount. */ @VisibleForTesting double calculateProducableAmountFactor(ProductionStorage storage, IWare requiredWare, IWare producableWare) { double stored = storage.getStored(requiredWare); double requiredForFullProduction = productionChain.getRequiredAmount(producableWare, requiredWare) * ONE_DAY_OF_WEEK; return Math.min(1.0, stored / requiredForFullProduction); } }
@VisibleForTesting Multimap<IWare, ETradeReason> collectTradeReasons(List<IWorkShop> workShops, ICity city) { Multimap<IWare, ETradeReason> map = ArrayListMultimap.create(); for (IWorkShop workShop : workShops) { map.put(workShop.getProducableWare(), ETradeReason.PRODUCED_WARE_IN_WORKSHOP); List<IWare> requiredWares = productionChain.getRequiredWares(workShop.getProducableWare()); requiredWares.stream().forEach(ware -> map.put(ware, ETradeReason.REQUIRE_FOR_PRODUCTION)); } for (IWare ware : city.getEffectiveProduction()) { map.put(ware, ETradeReason.PRODUCED_WARE_IN_CITY); List<IWare> requiredWares = productionChain.getRequiredWares(ware); requiredWares.stream().forEach(reqWare -> map.put(reqWare, ETradeReason.REQUIRE_FOR_CITY_PRODUCTION)); } for (IWare ware : city.getIneffectiveProduction()) { map.put(ware, ETradeReason.PRODUCED_WARE_IN_CITY); List<IWare> requiredWares = productionChain.getRequiredWares(ware); requiredWares.stream().forEach(reqWare -> map.put(reqWare, ETradeReason.REQUIRE_FOR_CITY_PRODUCTION)); } tradeService.getBasicNeeds().stream().forEach(ware -> map.put(ware, ETradeReason.REQUIRE_FOR_BASIC_NEEDS)); return map; }
public int getTheoreticalProducableAmount(IWare ware, ICity city) { if (!isProducable(city, ware)) { return 0; } double adjustmentFactor = 1; if (!isEffectiveProduction(city, ware)) { adjustmentFactor = inefficiencyFactor; } int population = city.getPopulationBinding().get(); int amountWorkshops = population / populationAmountPerWorkshop + 1; // Get the max amount that is producable return (int) Math.rint(productionChain.getProduction(ware) * amountWorkshops * adjustmentFactor); }
/** * Calculate the cost of wares that are consumed in one days production. * The ware is removed from storage in the process. * @param producedWare the ware that is produced. * @param storage where the ware is stored. * @param requiredWareFactor adjustment factor considering, that there may not be a full production due to * missing wares or under staffing. * @param ware that is required for the production * @return the average price of the consumed ware, with the amount taken into account. */ @VisibleForTesting double calculateWareCost(IWare producedWare, ProductionStorage storage, double requiredWareFactor, IWare ware) { double requiredForFullProduction = productionChain.getRequiredAmount(producedWare, ware) * ONE_DAY_OF_WEEK; double remove = -requiredForFullProduction * requiredWareFactor; double price = storage.getAvgPrice(ware); double moved = -storage.transfer(ware, remove, price); return moved * price; }
IWare produceWare = missionData.getProduceWare(); List<IWare> requiredWares = new LinkedList(); requiredWares.addAll(productionChain.getRequiredWares(produceWare)); IProductionConsumptionKnowledge knowledge = player.getProductionAndConsumptionKnowledge(); ICity nextStop;
public Map<IWare, Double> calculateConsumptionByProductionChain(ICity city) { List<IWare> wares = collectProducableWares(city); Map<IWare, Double> requireWares = new HashMap<>(); for (IWare ware : wares) { double adjustmentFactor = 1; if (!isEffectiveProduction(city, ware)) { adjustmentFactor = inefficiencyFactor; } if (city.getImported().contains(ware)) { if (isEffectiveProduction(city, ware)) { adjustmentFactor = inefficiencyFactor; } else { continue; } } int population = city.getPopulationBinding().get(); int amountWorkshops = population / populationAmountPerWorkshop + 1; List<IWare> required = productionChain.getRequiredWares(ware); for (IWare requiredWare : required) { double requiredAmount = productionChain.getRequiredAmount(ware, requiredWare) * amountWorkshops * adjustmentFactor; if (requireWares.containsKey(requiredWare)) { double update = requireWares.get(requiredWare) + requiredAmount; requireWares.put(requiredWare, update); } else { requireWares.put(requiredWare, requiredAmount); } } } return requireWares; }
} else { return (int)(workShops.stream() .filter(workshop -> productionChain.getRequiredAmount(workshop.getProducableWare(), ware) > 0) .mapToInt(workshop -> (int)Math.ceil(productionChain.getRequiredAmount(workshop.getProducableWare(), ware))) .sum() * 0.5); .filter(workshop -> productionChain.getRequiredAmount(workshop.getProducableWare(), ware) > 0) .mapToInt(workshop -> (int)Math.ceil(productionChain.getRequiredAmount(workshop.getProducableWare(), ware))) .sum(); default:
private void prepareForProductionNextWeekAndMakeAvailable(ICity city, IWare ware) { double producedAmount = getExactOutputCurrentWeek(ware, city); int makeAvailableAmount = (int) Math.floor(producedAmount); double remainingAmount = producedAmount - makeAvailableAmount; ProductionStorage storage = cityProductionStorage.getStorage(city); storage.transfer(ware, remainingAmount, 0); if (storage.getStored(ware) > 1) { int fromStorage = (int) Math.floor(storage.getStored(ware)); storage.transfer(ware, -fromStorage, 0); makeAvailableAmount += fromStorage; } city.move(ware, makeAvailableAmount, null); List<IWare> requiredWares = productionChain.getRequiredWares(ware); double adjustmentFactor = 1; if (!isEffectiveProduction(city, ware) || city.getImported().contains(ware)) { adjustmentFactor = inefficiencyFactor; } int population = city.getPopulationBinding().get(); int amountWorkshops = population / populationAmountPerWorkshop + 1; for (IWare requiredWare : requiredWares) { double requiredAmount = productionChain.getRequiredAmount(ware, requiredWare) * amountWorkshops * adjustmentFactor; double storedAmount = storage.getStored(requiredWare); double removeAmount = Math.min(requiredAmount, storedAmount); storage.transfer(requiredWare, -removeAmount, 0); } } }
for (IWorkShop workshop : workshops) { IWare producedWare = workshop.getProducableWare(); List<IWare> required = productionChain.getRequiredWares(producedWare); ProductionStorage storage = workshop.getStorage(); for (IWare ware : required) { double requiredAmount = productionChain.getRequiredAmount(producedWare, ware) * ONE_DAY_OF_WEEK; if (storage.getStored(ware) < requiredAmount) {