package games.strategy.triplea.ai.proAI.data; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import games.strategy.engine.data.GameData; import games.strategy.engine.data.NamedAttachable; import games.strategy.engine.data.PlayerID; import games.strategy.engine.data.ProductionFrontier; import games.strategy.engine.data.ProductionRule; import games.strategy.engine.data.UnitType; import games.strategy.triplea.ai.proAI.logging.ProLogger; import games.strategy.triplea.attachments.UnitAttachment; import games.strategy.triplea.delegate.Matches; public class ProPurchaseOptionMap { private final List<ProPurchaseOption> landFodderOptions; private final List<ProPurchaseOption> landAttackOptions; private final List<ProPurchaseOption> landDefenseOptions; private final List<ProPurchaseOption> airOptions; private final List<ProPurchaseOption> seaDefenseOptions; private final List<ProPurchaseOption> seaTransportOptions; private final List<ProPurchaseOption> seaCarrierOptions; private final List<ProPurchaseOption> seaSubOptions; private final List<ProPurchaseOption> aaOptions; private final List<ProPurchaseOption> factoryOptions; private final List<ProPurchaseOption> specialOptions; public ProPurchaseOptionMap(final PlayerID player, final GameData data) { ProLogger.info("Purchase Options"); // Initialize lists landFodderOptions = new ArrayList<>(); landAttackOptions = new ArrayList<>(); landDefenseOptions = new ArrayList<>(); airOptions = new ArrayList<>(); seaDefenseOptions = new ArrayList<>(); seaTransportOptions = new ArrayList<>(); seaCarrierOptions = new ArrayList<>(); seaSubOptions = new ArrayList<>(); aaOptions = new ArrayList<>(); factoryOptions = new ArrayList<>(); specialOptions = new ArrayList<>(); // Add each production rule to appropriate list(s) final ProductionFrontier productionFrontier = player.getProductionFrontier(); if (productionFrontier == null || productionFrontier.getRules() == null) { return; } for (final ProductionRule rule : productionFrontier.getRules()) { // Check if rule is for a unit final NamedAttachable resourceOrUnit = rule.getResults().keySet().iterator().next(); if (!(resourceOrUnit instanceof UnitType)) { continue; } final UnitType unitType = (UnitType) resourceOrUnit; // Add rule to appropriate purchase option list if ((UnitAttachment.get(unitType).getMovement(player) <= 0 && !(UnitAttachment.get(unitType).getCanProduceUnits())) || Matches.UnitTypeConsumesUnitsOnCreation.match(unitType) || UnitAttachment.get(unitType).getIsSuicide()) { final ProPurchaseOption ppo = new ProPurchaseOption(rule, unitType, player, data); specialOptions.add(ppo); ProLogger.debug("Special: " + ppo); } else if (Matches.UnitTypeCanProduceUnits.match(unitType) && Matches.UnitTypeIsInfrastructure.match(unitType)) { final ProPurchaseOption ppo = new ProPurchaseOption(rule, unitType, player, data); factoryOptions.add(ppo); ProLogger.debug("Factory: " + ppo); } else if (Matches.UnitTypeIsAAforBombingThisUnitOnly.match(unitType)) { final ProPurchaseOption ppo = new ProPurchaseOption(rule, unitType, player, data); aaOptions.add(ppo); ProLogger.debug("AA: " + ppo); } else if (Matches.UnitTypeIsLand.match(unitType)) { final ProPurchaseOption ppo = new ProPurchaseOption(rule, unitType, player, data); landFodderOptions.add(ppo); if (ppo.getAttack() >= ppo.getDefense() || ppo.isAttackSupport() || ppo.getMovement() > 1) { landAttackOptions.add(ppo); } if (ppo.getDefense() >= ppo.getAttack() || ppo.isDefenseSupport() || ppo.getMovement() > 1) { landDefenseOptions.add(ppo); } ProLogger.debug("Land: " + ppo); } else if (Matches.UnitTypeIsAir.match(unitType)) { final ProPurchaseOption ppo = new ProPurchaseOption(rule, unitType, player, data); airOptions.add(ppo); ProLogger.debug("Air: " + ppo); } else if (Matches.UnitTypeIsSea.match(unitType)) { final ProPurchaseOption ppo = new ProPurchaseOption(rule, unitType, player, data); if (!ppo.isSub()) { seaDefenseOptions.add(ppo); } if (ppo.isTransport()) { seaTransportOptions.add(ppo); } if (ppo.isCarrier()) { seaCarrierOptions.add(ppo); } if (ppo.isSub()) { seaSubOptions.add(ppo); } ProLogger.debug("Sea: " + ppo); } } if (landAttackOptions.isEmpty()) { landAttackOptions.addAll(landDefenseOptions); } if (landDefenseOptions.isEmpty()) { landDefenseOptions.addAll(landAttackOptions); } // Print categorized options ProLogger.info("Purchase Categories"); logOptions(landFodderOptions, "Land Fodder Options: "); logOptions(landAttackOptions, "Land Attack Options: "); logOptions(landDefenseOptions, "Land Defense Options: "); logOptions(airOptions, "Air Options: "); logOptions(seaDefenseOptions, "Sea Defense Options: "); logOptions(seaTransportOptions, "Sea Transport Options: "); logOptions(seaCarrierOptions, "Sea Carrier Options: "); logOptions(seaSubOptions, "Sea Sub Options: "); logOptions(aaOptions, "AA Options: "); logOptions(factoryOptions, "Factory Options: "); logOptions(specialOptions, "Special Options: "); } public List<ProPurchaseOption> getAllOptions() { final Set<ProPurchaseOption> allOptions = new HashSet<>(); allOptions.addAll(getLandOptions()); allOptions.addAll(airOptions); allOptions.addAll(getSeaOptions()); allOptions.addAll(aaOptions); allOptions.addAll(factoryOptions); allOptions.addAll(specialOptions); return new ArrayList<>(allOptions); } public List<ProPurchaseOption> getLandOptions() { final Set<ProPurchaseOption> landOptions = new HashSet<>(); landOptions.addAll(landFodderOptions); landOptions.addAll(landAttackOptions); landOptions.addAll(landDefenseOptions); return new ArrayList<>(landOptions); } public List<ProPurchaseOption> getSeaOptions() { final Set<ProPurchaseOption> seaOptions = new HashSet<>(); seaOptions.addAll(seaDefenseOptions); seaOptions.addAll(seaTransportOptions); seaOptions.addAll(seaCarrierOptions); seaOptions.addAll(seaSubOptions); return new ArrayList<>(seaOptions); } public List<ProPurchaseOption> getLandFodderOptions() { return landFodderOptions; } public List<ProPurchaseOption> getLandAttackOptions() { return landAttackOptions; } public List<ProPurchaseOption> getLandDefenseOptions() { return landDefenseOptions; } public List<ProPurchaseOption> getAirOptions() { return airOptions; } public List<ProPurchaseOption> getSeaDefenseOptions() { return seaDefenseOptions; } public List<ProPurchaseOption> getSeaTransportOptions() { return seaTransportOptions; } public List<ProPurchaseOption> getSeaCarrierOptions() { return seaCarrierOptions; } public List<ProPurchaseOption> getSeaSubOptions() { return seaSubOptions; } public List<ProPurchaseOption> getAAOptions() { return aaOptions; } public List<ProPurchaseOption> getFactoryOptions() { return factoryOptions; } public List<ProPurchaseOption> getSpecialOptions() { return specialOptions; } private void logOptions(final List<ProPurchaseOption> purchaseOptions, final String name) { final StringBuilder sb = new StringBuilder(name); for (final ProPurchaseOption ppo : purchaseOptions) { sb.append(ppo.getUnitType().getName()); sb.append(", "); } sb.delete(sb.length() - 2, sb.length()); ProLogger.debug(sb.toString()); } }