Search in sources :

Example 16 with Resource

use of games.strategy.engine.data.Resource 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 17 with Resource

use of games.strategy.engine.data.Resource 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)

Example 18 with Resource

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

the class ProTechAi method tech.

static void tech(final ITechDelegate techDelegate, final GameData data, final PlayerID player) {
    if (!Properties.getWW2V3TechModel(data)) {
        return;
    }
    final Territory myCapitol = TerritoryAttachment.getFirstOwnedCapitalOrFirstUnownedCapital(player, data);
    final float enemyStrength = getStrengthOfPotentialAttackers(myCapitol, data, player);
    float myStrength = (myCapitol == null || myCapitol.getUnits() == null) ? 0.0F : strength(myCapitol.getUnits().getUnits(), false, false, false);
    final List<Territory> areaStrength = getNeighboringLandTerritories(data, player, myCapitol);
    for (final Territory areaTerr : areaStrength) {
        myStrength += strength(areaTerr.getUnits().getUnits(), false, false, false) * 0.75F;
    }
    final boolean capDanger = myStrength < (enemyStrength * 1.25F + 3.0F);
    final Resource pus = data.getResourceList().getResource(Constants.PUS);
    final int pusRemaining = player.getResources().getQuantity(pus);
    final Resource techtokens = data.getResourceList().getResource(Constants.TECH_TOKENS);
    final int techTokensQuantity = player.getResources().getQuantity(techtokens);
    int tokensToBuy = 0;
    if (!capDanger && techTokensQuantity < 3 && pusRemaining > Math.random() * 160) {
        tokensToBuy = 1;
    }
    if (techTokensQuantity > 0 || tokensToBuy > 0) {
        final List<TechnologyFrontier> cats = TechAdvance.getPlayerTechCategories(player);
        // retaining 65% chance of choosing land advances using basic ww2v3 model.
        if (data.getTechnologyFrontier().isEmpty()) {
            if (Math.random() > 0.35) {
                techDelegate.rollTech(techTokensQuantity + tokensToBuy, cats.get(1), tokensToBuy, null);
            } else {
                techDelegate.rollTech(techTokensQuantity + tokensToBuy, cats.get(0), tokensToBuy, null);
            }
        } else {
            final int rand = (int) (Math.random() * cats.size());
            techDelegate.rollTech(techTokensQuantity + tokensToBuy, cats.get(rand), tokensToBuy, null);
        }
    }
}
Also used : Territory(games.strategy.engine.data.Territory) Resource(games.strategy.engine.data.Resource) TechnologyFrontier(games.strategy.engine.data.TechnologyFrontier)

Example 19 with Resource

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

the class ProPurchaseUtils method getCost.

/**
 * How many PU's does it cost the given player to produce the given unit including any dependents.
 */
public static double getCost(final Unit unit) {
    final Resource pus = unit.getData().getResourceList().getResource(Constants.PUS);
    final Collection<Unit> units = TransportTracker.transportingAndUnloaded(unit);
    units.add(unit);
    double cost = 0.0;
    for (final Unit u : units) {
        final ProductionRule rule = getProductionRule(u.getType(), u.getOwner());
        if (rule == null) {
            cost += ProData.unitValueMap.getInt(u.getType());
        } else {
            cost += ((double) rule.getCosts().getInt(pus)) / rule.getResults().totalValues();
        }
    }
    return cost;
}
Also used : ProductionRule(games.strategy.engine.data.ProductionRule) Resource(games.strategy.engine.data.Resource) TripleAUnit(games.strategy.triplea.TripleAUnit) Unit(games.strategy.engine.data.Unit)

Example 20 with Resource

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

the class AiUtils method getCost.

/**
 * How many PU's does it cost the given player to produce the given unit type.
 *
 * <p>
 * If the player cannot produce the given unit, return Integer.MAX_VALUE
 * </p>
 */
static int getCost(final UnitType unitType, final PlayerID player, final GameData data) {
    final Resource pus = data.getResourceList().getResource(Constants.PUS);
    final ProductionRule rule = getProductionRule(unitType, player);
    return (rule == null) ? Integer.MAX_VALUE : rule.getCosts().getInt(pus);
}
Also used : ProductionRule(games.strategy.engine.data.ProductionRule) Resource(games.strategy.engine.data.Resource)

Aggregations

Resource (games.strategy.engine.data.Resource)71 PlayerID (games.strategy.engine.data.PlayerID)22 IntegerMap (games.strategy.util.IntegerMap)16 GameData (games.strategy.engine.data.GameData)15 Unit (games.strategy.engine.data.Unit)15 ArrayList (java.util.ArrayList)15 Territory (games.strategy.engine.data.Territory)14 UnitType (games.strategy.engine.data.UnitType)13 Change (games.strategy.engine.data.Change)11 CompositeChange (games.strategy.engine.data.CompositeChange)11 ProductionRule (games.strategy.engine.data.ProductionRule)10 TripleAUnit (games.strategy.triplea.TripleAUnit)10 NamedAttachable (games.strategy.engine.data.NamedAttachable)9 ResourceCollection (games.strategy.engine.data.ResourceCollection)8 PlayerAttachment (games.strategy.triplea.attachments.PlayerAttachment)7 GameParseException (games.strategy.engine.data.GameParseException)6 UnitAttachment (games.strategy.triplea.attachments.UnitAttachment)6 HashMap (java.util.HashMap)6 HashSet (java.util.HashSet)6 Test (org.junit.jupiter.api.Test)5