use of games.strategy.engine.data.RepairRule in project triplea by triplea-game.
the class GameDataExporter method repairRules.
private void repairRules(final GameData data) {
for (final RepairRule rr : data.getRepairRuleList().getRepairRules()) {
xmlfile.append(" <repairRule name=\"").append(rr.getName()).append("\">\n");
for (final Resource cost : rr.getCosts().keySet()) {
xmlfile.append(" <cost resource=\"").append(cost.getName()).append("\" quantity=\"").append(rr.getCosts().getInt(cost)).append("\"/>\n");
}
for (final NamedAttachable result : rr.getResults().keySet()) {
xmlfile.append(" <result resourceOrUnit=\"").append(result.getName()).append("\" quantity=\"").append(rr.getResults().getInt(result)).append("\"/>\n");
}
xmlfile.append(" </repairRule>\n");
}
}
use of games.strategy.engine.data.RepairRule in project triplea by triplea-game.
the class GameDataExporter method repairFrontiers.
private void repairFrontiers(final GameData data) {
for (final String frontierName : data.getRepairFrontierList().getRepairFrontierNames()) {
final RepairFrontier frontier = data.getRepairFrontierList().getRepairFrontier(frontierName);
xmlfile.append("\n");
xmlfile.append(" <repairFrontier name=\"").append(frontier.getName()).append("\">\n");
for (final RepairRule rule : frontier.getRules()) {
xmlfile.append(" <repairRules name=\"").append(rule.getName()).append("\"/>\n");
}
xmlfile.append(" </repairFrontier>\n");
}
xmlfile.append("\n");
}
use of games.strategy.engine.data.RepairRule 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();
}
use of games.strategy.engine.data.RepairRule in project triplea by triplea-game.
the class ProductionRepairPanel method getProduction.
private HashMap<Unit, IntegerMap<RepairRule>> getProduction() {
final HashMap<Unit, IntegerMap<RepairRule>> prod = new HashMap<>();
for (final Rule rule : rules) {
final int quantity = rule.getQuantity();
if (quantity != 0) {
final IntegerMap<RepairRule> repairRule = new IntegerMap<>();
final Unit unit = rule.getUnit();
repairRule.put(rule.getProductionRule(), quantity);
prod.put(unit, repairRule);
}
}
return prod;
}
use of games.strategy.engine.data.RepairRule in project triplea by triplea-game.
the class PurchaseDelegate method getRepairCosts.
private IntegerMap<Resource> getRepairCosts(final Map<Unit, IntegerMap<RepairRule>> repairRules, final PlayerID player) {
final IntegerMap<Resource> costs = new IntegerMap<>();
for (final IntegerMap<RepairRule> map : repairRules.values()) {
for (final RepairRule rule : map.keySet()) {
costs.addMultiple(rule.getCosts(), map.getInt(rule));
}
}
final double discount = TechAbilityAttachment.getRepairDiscount(player, getData());
if (discount != 1.0D) {
costs.multiplyAllValuesBy(discount, 3);
}
return costs;
}
Aggregations