Search in sources :

Example 1 with ProductionRule

use of games.strategy.engine.data.ProductionRule in project triplea by triplea-game.

the class InitializationDelegate method initDestroyerArtillery.

private static void initDestroyerArtillery(final IDelegateBridge bridge) {
    final GameData data = bridge.getData();
    final boolean addArtilleryAndDestroyers = Properties.getUseDestroyersAndArtillery(data);
    if (!isWW2V2(data) && addArtilleryAndDestroyers) {
        final CompositeChange change = new CompositeChange();
        final ProductionRule artillery = data.getProductionRuleList().getProductionRule("buyArtillery");
        final ProductionRule destroyer = data.getProductionRuleList().getProductionRule("buyDestroyer");
        final ProductionFrontier frontier = data.getProductionFrontierList().getProductionFrontier("production");
        if (artillery != null && !frontier.getRules().contains(artillery)) {
            change.add(ChangeFactory.addProductionRule(artillery, frontier));
        }
        if (destroyer != null && !frontier.getRules().contains(destroyer)) {
            change.add(ChangeFactory.addProductionRule(destroyer, frontier));
        }
        final ProductionRule artilleryIndustrialTechnology = data.getProductionRuleList().getProductionRule("buyArtilleryIndustrialTechnology");
        final ProductionRule destroyerIndustrialTechnology = data.getProductionRuleList().getProductionRule("buyDestroyerIndustrialTechnology");
        final ProductionFrontier frontierIndustrialTechnology = data.getProductionFrontierList().getProductionFrontier("productionIndustrialTechnology");
        if (artilleryIndustrialTechnology != null && !frontierIndustrialTechnology.getRules().contains(artilleryIndustrialTechnology)) {
            change.add(ChangeFactory.addProductionRule(artilleryIndustrialTechnology, frontierIndustrialTechnology));
        }
        if (destroyerIndustrialTechnology != null && !frontierIndustrialTechnology.getRules().contains(destroyerIndustrialTechnology)) {
            change.add(ChangeFactory.addProductionRule(destroyerIndustrialTechnology, frontierIndustrialTechnology));
        }
        if (!change.isEmpty()) {
            bridge.getHistoryWriter().startEvent("Adding destroyers and artillery production rules");
            bridge.addChange(change);
        }
    }
}
Also used : GameData(games.strategy.engine.data.GameData) ProductionRule(games.strategy.engine.data.ProductionRule) CompositeChange(games.strategy.engine.data.CompositeChange) ProductionFrontier(games.strategy.engine.data.ProductionFrontier)

Example 2 with ProductionRule

use of games.strategy.engine.data.ProductionRule in project triplea by triplea-game.

the class InitializationDelegate method initShipyards.

private static void initShipyards(final IDelegateBridge bridge) {
    final GameData data = bridge.getData();
    final boolean useShipyards = Properties.getUseShipyards(data);
    if (useShipyards) {
        final CompositeChange change = new CompositeChange();
        final ProductionFrontier frontierShipyards = data.getProductionFrontierList().getProductionFrontier("productionShipyards");
        /*
       * Find the productionRules, if the unit is NOT a sea unit, add it to the ShipYards prod rule.
       */
        final ProductionFrontier frontierNonShipyards = data.getProductionFrontierList().getProductionFrontier("production");
        final Collection<ProductionRule> rules = frontierNonShipyards.getRules();
        for (final ProductionRule rule : rules) {
            final String ruleName = rule.getName();
            final IntegerMap<NamedAttachable> ruleResults = rule.getResults();
            final NamedAttachable named = ruleResults.keySet().iterator().next();
            if (!(named instanceof UnitType)) {
                continue;
            }
            final UnitType unit = data.getUnitTypeList().getUnitType(named.getName());
            final boolean isSea = UnitAttachment.get(unit).getIsSea();
            if (!isSea) {
                final ProductionRule prodRule = data.getProductionRuleList().getProductionRule(ruleName);
                change.add(ChangeFactory.addProductionRule(prodRule, frontierShipyards));
            }
        }
        bridge.getHistoryWriter().startEvent("Adding shipyard production rules - land/air units");
        bridge.addChange(change);
    }
}
Also used : GameData(games.strategy.engine.data.GameData) ProductionRule(games.strategy.engine.data.ProductionRule) NamedAttachable(games.strategy.engine.data.NamedAttachable) UnitType(games.strategy.engine.data.UnitType) CompositeChange(games.strategy.engine.data.CompositeChange) ProductionFrontier(games.strategy.engine.data.ProductionFrontier)

Example 3 with ProductionRule

use of games.strategy.engine.data.ProductionRule in project triplea by triplea-game.

the class GameDataExporter method productionFrontiers.

private void productionFrontiers(final GameData data) {
    for (final String frontierName : data.getProductionFrontierList().getProductionFrontierNames()) {
        final ProductionFrontier frontier = data.getProductionFrontierList().getProductionFrontier(frontierName);
        xmlfile.append("\n");
        xmlfile.append("        <productionFrontier name=\"").append(frontier.getName()).append("\">\n");
        for (final ProductionRule rule : frontier.getRules()) {
            xmlfile.append("            <frontierRules name=\"").append(rule.getName()).append("\"/>\n");
        }
        xmlfile.append("        </productionFrontier>\n");
    }
    xmlfile.append("\n");
}
Also used : ProductionRule(games.strategy.engine.data.ProductionRule) ProductionFrontier(games.strategy.engine.data.ProductionFrontier)

Example 4 with ProductionRule

use of games.strategy.engine.data.ProductionRule in project triplea by triplea-game.

the class GameDataExporter method productionRules.

private void productionRules(final GameData data) {
    for (final ProductionRule pr : data.getProductionRuleList().getProductionRules()) {
        xmlfile.append("        <productionRule name=\"").append(pr.getName()).append("\">\n");
        for (final Resource cost : pr.getCosts().keySet()) {
            xmlfile.append("            <cost resource=\"").append(cost.getName()).append("\" quantity=\"").append(pr.getCosts().getInt(cost)).append("\"/>\n");
        }
        for (final NamedAttachable result : pr.getResults().keySet()) {
            xmlfile.append("            <result resourceOrUnit=\"").append(result.getName()).append("\" quantity=\"").append(pr.getResults().getInt(result)).append("\"/>\n");
        }
        xmlfile.append("        </productionRule>\n");
    }
}
Also used : ProductionRule(games.strategy.engine.data.ProductionRule) NamedAttachable(games.strategy.engine.data.NamedAttachable) Resource(games.strategy.engine.data.Resource)

Example 5 with ProductionRule

use of games.strategy.engine.data.ProductionRule in project triplea by triplea-game.

the class WeakAi method purchase.

@Override
public void purchase(final boolean purchaseForBid, final int pusToSpend, final IPurchaseDelegate purchaseDelegate, final GameData data, final PlayerID player) {
    if (purchaseForBid) {
        // bid will only buy land units, due to weak ai placement for bid not being able to handle sea units
        final Resource pus = data.getResourceList().getResource(Constants.PUS);
        int leftToSpend = pusToSpend;
        final List<ProductionRule> rules = player.getProductionFrontier().getRules();
        final IntegerMap<ProductionRule> purchase = new IntegerMap<>();
        int minCost = Integer.MAX_VALUE;
        int i = 0;
        while ((minCost == Integer.MAX_VALUE || leftToSpend >= minCost) && i < 100000) {
            i++;
            for (final ProductionRule rule : rules) {
                final NamedAttachable resourceOrUnit = rule.getResults().keySet().iterator().next();
                if (!(resourceOrUnit instanceof UnitType)) {
                    continue;
                }
                final UnitType results = (UnitType) resourceOrUnit;
                if (Matches.unitTypeIsSea().test(results) || Matches.unitTypeIsAir().test(results) || Matches.unitTypeIsInfrastructure().test(results) || Matches.unitTypeIsAaForAnything().test(results) || Matches.unitTypeHasMaxBuildRestrictions().test(results) || Matches.unitTypeConsumesUnitsOnCreation().test(results) || Matches.unitTypeIsStatic(player).test(results)) {
                    continue;
                }
                final int cost = rule.getCosts().getInt(pus);
                if (cost < 1) {
                    continue;
                }
                if (minCost == Integer.MAX_VALUE) {
                    minCost = cost;
                }
                if (minCost > cost) {
                    minCost = cost;
                }
                // give a preference to cheap units
                if (Math.random() * cost < 2) {
                    if (cost <= leftToSpend) {
                        leftToSpend -= cost;
                        purchase.add(rule, 1);
                    }
                }
            }
        }
        purchaseDelegate.purchase(purchase);
        pause();
        return;
    }
    final boolean isAmphib = isAmphibAttack(player, data);
    final Route amphibRoute = getAmphibRoute(player, data);
    final int transportCount = countTransports(data, player);
    final int landUnitCount = countLandUnits(data, player);
    int defUnitsAtAmpibRoute = 0;
    if (isAmphib && amphibRoute != null) {
        defUnitsAtAmpibRoute = amphibRoute.getEnd().getUnits().getUnitCount();
    }
    final Resource pus = data.getResourceList().getResource(Constants.PUS);
    final int totalPu = player.getResources().getQuantity(pus);
    int leftToSpend = totalPu;
    final Territory capitol = TerritoryAttachment.getFirstOwnedCapitalOrFirstUnownedCapital(player, data);
    final List<ProductionRule> rules = player.getProductionFrontier().getRules();
    final IntegerMap<ProductionRule> purchase = new IntegerMap<>();
    final List<RepairRule> repairRules;
    final Predicate<Unit> ourFactories = Matches.unitIsOwnedBy(player).and(Matches.unitCanProduceUnits());
    final List<Territory> repairFactories = CollectionUtils.getMatches(Utils.findUnitTerr(data, ourFactories), Matches.isTerritoryOwnedBy(player));
    // figure out if anything needs to be repaired
    if (player.getRepairFrontier() != null && Properties.getDamageFromBombingDoneToUnitsInsteadOfTerritories(data)) {
        repairRules = player.getRepairFrontier().getRules();
        final IntegerMap<RepairRule> repairMap = new IntegerMap<>();
        final HashMap<Unit, IntegerMap<RepairRule>> repair = new HashMap<>();
        final Map<Unit, Territory> unitsThatCanProduceNeedingRepair = new HashMap<>();
        final int minimumUnitPrice = 3;
        int diff;
        int capProduction = 0;
        Unit capUnit = null;
        Territory capUnitTerritory = null;
        int currentProduction = 0;
        // we should sort this
        Collections.shuffle(repairFactories);
        for (final Territory fixTerr : repairFactories) {
            if (!Matches.territoryIsOwnedAndHasOwnedUnitMatching(player, Matches.unitCanProduceUnitsAndCanBeDamaged()).test(fixTerr)) {
                continue;
            }
            final Unit possibleFactoryNeedingRepair = TripleAUnit.getBiggestProducer(CollectionUtils.getMatches(fixTerr.getUnits().getUnits(), ourFactories), fixTerr, player, data, false);
            if (Matches.unitHasTakenSomeBombingUnitDamage().test(possibleFactoryNeedingRepair)) {
                unitsThatCanProduceNeedingRepair.put(possibleFactoryNeedingRepair, fixTerr);
            }
            if (fixTerr == capitol) {
                capProduction = TripleAUnit.getHowMuchCanUnitProduce(possibleFactoryNeedingRepair, fixTerr, player, data, true, true);
                capUnit = possibleFactoryNeedingRepair;
                capUnitTerritory = fixTerr;
            }
            currentProduction += TripleAUnit.getHowMuchCanUnitProduce(possibleFactoryNeedingRepair, fixTerr, player, data, true, true);
        }
        repairFactories.remove(capitol);
        unitsThatCanProduceNeedingRepair.remove(capUnit);
        // assume minimum unit price is 3, and that we are buying only that... if we over repair, oh well, that is better
        // than under-repairing
        // goal is to be able to produce all our units, and at least half of that production in the capitol
        // 
        // if capitol is super safe, we don't have to do this. and if capitol is under siege, we should repair enough to
        // place all our units here
        int maxUnits = (totalPu - 1) / minimumUnitPrice;
        if ((capProduction <= maxUnits / 2 || repairFactories.isEmpty()) && capUnit != null) {
            for (final RepairRule rrule : repairRules) {
                if (!capUnit.getType().equals(rrule.getResults().keySet().iterator().next())) {
                    continue;
                }
                if (!Matches.territoryIsOwnedAndHasOwnedUnitMatching(player, Matches.unitCanProduceUnitsAndCanBeDamaged()).test(capitol)) {
                    continue;
                }
                final TripleAUnit taUnit = (TripleAUnit) capUnit;
                diff = taUnit.getUnitDamage();
                final int unitProductionAllowNegative = TripleAUnit.getHowMuchCanUnitProduce(capUnit, capUnitTerritory, player, data, false, true) - diff;
                if (!repairFactories.isEmpty()) {
                    diff = Math.min(diff, (maxUnits / 2 - unitProductionAllowNegative) + 1);
                } else {
                    diff = Math.min(diff, (maxUnits - unitProductionAllowNegative));
                }
                diff = Math.min(diff, leftToSpend - minimumUnitPrice);
                if (diff > 0) {
                    if (unitProductionAllowNegative >= 0) {
                        currentProduction += diff;
                    } else {
                        currentProduction += diff + unitProductionAllowNegative;
                    }
                    repairMap.add(rrule, diff);
                    repair.put(capUnit, repairMap);
                    leftToSpend -= diff;
                    purchaseDelegate.purchaseRepair(repair);
                    repair.clear();
                    repairMap.clear();
                    // ideally we would adjust this after each single PU spent, then re-evaluate
                    // everything.
                    maxUnits = (leftToSpend - 1) / minimumUnitPrice;
                }
            }
        }
        int i = 0;
        while (currentProduction < maxUnits && i < 2) {
            for (final RepairRule rrule : repairRules) {
                for (final Unit fixUnit : unitsThatCanProduceNeedingRepair.keySet()) {
                    if (fixUnit == null || !fixUnit.getType().equals(rrule.getResults().keySet().iterator().next())) {
                        continue;
                    }
                    if (!Matches.territoryIsOwnedAndHasOwnedUnitMatching(player, Matches.unitCanProduceUnitsAndCanBeDamaged()).test(unitsThatCanProduceNeedingRepair.get(fixUnit))) {
                        continue;
                    }
                    // territories
                    if (currentProduction >= maxUnits) {
                        continue;
                    }
                    final TripleAUnit taUnit = (TripleAUnit) fixUnit;
                    diff = taUnit.getUnitDamage();
                    final int unitProductionAllowNegative = TripleAUnit.getHowMuchCanUnitProduce(fixUnit, unitsThatCanProduceNeedingRepair.get(fixUnit), player, data, false, true) - diff;
                    if (i == 0) {
                        if (unitProductionAllowNegative < 0) {
                            diff = Math.min(diff, (maxUnits - currentProduction) - unitProductionAllowNegative);
                        } else {
                            diff = Math.min(diff, (maxUnits - currentProduction));
                        }
                    }
                    diff = Math.min(diff, leftToSpend - minimumUnitPrice);
                    if (diff > 0) {
                        if (unitProductionAllowNegative >= 0) {
                            currentProduction += diff;
                        } else {
                            currentProduction += diff + unitProductionAllowNegative;
                        }
                        repairMap.add(rrule, diff);
                        repair.put(fixUnit, repairMap);
                        leftToSpend -= diff;
                        purchaseDelegate.purchaseRepair(repair);
                        repair.clear();
                        repairMap.clear();
                        // ideally we would adjust this after each single PU spent, then re-evaluate
                        // everything.
                        maxUnits = (leftToSpend - 1) / minimumUnitPrice;
                    }
                }
            }
            repairFactories.add(capitol);
            if (capUnit != null) {
                unitsThatCanProduceNeedingRepair.put(capUnit, capUnitTerritory);
            }
            i++;
        }
    }
    int minCost = Integer.MAX_VALUE;
    int i = 0;
    while ((minCost == Integer.MAX_VALUE || leftToSpend >= minCost) && i < 100000) {
        i++;
        for (final ProductionRule rule : rules) {
            final NamedAttachable resourceOrUnit = rule.getResults().keySet().iterator().next();
            if (!(resourceOrUnit instanceof UnitType)) {
                continue;
            }
            final UnitType results = (UnitType) resourceOrUnit;
            if (Matches.unitTypeIsAir().test(results) || Matches.unitTypeIsInfrastructure().test(results) || Matches.unitTypeIsAaForAnything().test(results) || Matches.unitTypeHasMaxBuildRestrictions().test(results) || Matches.unitTypeConsumesUnitsOnCreation().test(results) || Matches.unitTypeIsStatic(player).test(results)) {
                continue;
            }
            final int transportCapacity = UnitAttachment.get(results).getTransportCapacity();
            // buy transports if we can be amphibious
            if (Matches.unitTypeIsSea().test(results)) {
                if (!isAmphib || transportCapacity <= 0) {
                    continue;
                }
            }
            final int cost = rule.getCosts().getInt(pus);
            if (cost < 1) {
                continue;
            }
            if (minCost == Integer.MAX_VALUE) {
                minCost = cost;
            }
            if (minCost > cost) {
                minCost = cost;
            }
            // give a preferene to cheap units, and to transports
            // but dont go overboard with buying transports
            int goodNumberOfTransports = 0;
            final boolean isTransport = transportCapacity > 0;
            if (amphibRoute != null) {
                // 25% transports - can be more if frontier is far away
                goodNumberOfTransports = (landUnitCount / 4);
                // boost for transport production
                if (isTransport && defUnitsAtAmpibRoute > goodNumberOfTransports && landUnitCount > defUnitsAtAmpibRoute && defUnitsAtAmpibRoute > transportCount) {
                    final int transports = (leftToSpend / cost);
                    leftToSpend -= cost * transports;
                    purchase.add(rule, transports);
                    continue;
                }
            }
            final boolean buyBecauseTransport = (Math.random() < 0.7 && transportCount < goodNumberOfTransports) || Math.random() < 0.10;
            final boolean dontBuyBecauseTooManyTransports = transportCount > 2 * goodNumberOfTransports;
            if ((!isTransport && Math.random() * cost < 2) || (isTransport && buyBecauseTransport && !dontBuyBecauseTooManyTransports)) {
                if (cost <= leftToSpend) {
                    leftToSpend -= cost;
                    purchase.add(rule, 1);
                }
            }
        }
    }
    purchaseDelegate.purchase(purchase);
    pause();
}
Also used : IntegerMap(games.strategy.util.IntegerMap) Territory(games.strategy.engine.data.Territory) NamedAttachable(games.strategy.engine.data.NamedAttachable) HashMap(java.util.HashMap) Resource(games.strategy.engine.data.Resource) RepairRule(games.strategy.engine.data.RepairRule) TripleAUnit(games.strategy.triplea.TripleAUnit) Unit(games.strategy.engine.data.Unit) TripleAUnit(games.strategy.triplea.TripleAUnit) ProductionRule(games.strategy.engine.data.ProductionRule) UnitType(games.strategy.engine.data.UnitType) Route(games.strategy.engine.data.Route)

Aggregations

ProductionRule (games.strategy.engine.data.ProductionRule)27 IntegerMap (games.strategy.util.IntegerMap)14 NamedAttachable (games.strategy.engine.data.NamedAttachable)10 Resource (games.strategy.engine.data.Resource)10 UnitType (games.strategy.engine.data.UnitType)10 Unit (games.strategy.engine.data.Unit)9 GameData (games.strategy.engine.data.GameData)8 ProductionFrontier (games.strategy.engine.data.ProductionFrontier)8 Territory (games.strategy.engine.data.Territory)8 HashMap (java.util.HashMap)8 HashSet (java.util.HashSet)8 PlayerID (games.strategy.engine.data.PlayerID)7 ArrayList (java.util.ArrayList)7 List (java.util.List)5 Map (java.util.Map)5 RepairRule (games.strategy.engine.data.RepairRule)4 Matches (games.strategy.triplea.delegate.Matches)4 CollectionUtils (games.strategy.util.CollectionUtils)4 Collection (java.util.Collection)4 LinkedHashMap (java.util.LinkedHashMap)4