Skip to content

Commit

Permalink
AI - place units on non infra factories (#3645)
Browse files Browse the repository at this point in the history
* Update purchase utilities to consider factory territory

* Update match to all factories

* Update method parameters and adding to place territories

* Add method comment
  • Loading branch information
ron-murhammer authored and ssoloff committed Jul 29, 2018
1 parent a1af515 commit 778591f
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1454,7 +1454,7 @@ private void removeAttacksUntilCapitalCanBeHeld(final List<ProTerritory> priorit
// Add max purchase defenders to capital for non-mobile factories (don't consider mobile factories since they may
// move elsewhere)
final List<Unit> placeUnits = new ArrayList<>();
if (ProMatches.territoryHasNonMobileInfraFactoryAndIsNotConqueredOwnedLand(player, data).test(myCapital)) {
if (ProMatches.territoryHasNonMobileFactoryAndIsNotConqueredOwnedLand(player, data).test(myCapital)) {
placeUnits.addAll(ProPurchaseUtils.findMaxPurchaseDefenders(player, myCapital, landPurchaseOptions));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ private void findUnitsThatCantMove(final Map<Territory, ProPurchaseTerritory> pu

// Add max defenders that can be purchased to each territory
for (final Territory t : moveMap.keySet()) {
if (ProMatches.territoryHasNonMobileInfraFactoryAndIsNotConqueredOwnedLand(player, data).test(t)) {
if (ProMatches.territoryHasNonMobileFactoryAndIsNotConqueredOwnedLand(player, data).test(t)) {
moveMap.get(t).getCantMoveUnits()
.addAll(ProPurchaseUtils.findMaxPurchaseDefenders(player, t, landPurchaseOptions));
}
Expand Down Expand Up @@ -521,7 +521,7 @@ private List<ProTerritory> prioritizeDefendOptions(final Map<Territory, ProTerri

// Add best sea production territory for sea factories
List<Territory> seaFactories = CollectionUtils.getMatches(data.getMap().getTerritories(),
ProMatches.territoryHasInfraFactoryAndIsNotConqueredOwnedLand(player, data));
ProMatches.territoryHasFactoryAndIsNotConqueredOwnedLand(player, data));
seaFactories = CollectionUtils.getMatches(seaFactories,
ProMatches.territoryHasInfraFactoryAndIsOwnedLandAdjacentToSea(player, data));
for (final Territory t : seaFactories) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ int repair(int pusRemaining, final IPurchaseDelegate purchaseDelegate, final Gam
.and(Matches.unitCanProduceUnits())
.and(Matches.unitIsInfrastructure());
final List<Territory> rfactories = CollectionUtils.getMatches(data.getMap().getTerritories(),
ProMatches.territoryHasInfraFactoryAndIsNotConqueredOwnedLand(player, data));
ProMatches.territoryHasFactoryAndIsNotConqueredOwnedLand(player, data));
if (player.getRepairFrontier() != null
&& Properties.getDamageFromBombingDoneToUnitsInsteadOfTerritories(data)) {
ProLogger.debug("Factories can be damaged");
Expand Down Expand Up @@ -578,8 +578,8 @@ private void purchaseDefenders(final Map<Territory, ProPurchaseTerritory> purcha
}

// Find defenders that can be produced in this territory
final List<ProPurchaseOption> purchaseOptionsForTerritory =
ProPurchaseUtils.findPurchaseOptionsForTerritory(player, defensePurchaseOptions, t, isBid);
final List<ProPurchaseOption> purchaseOptionsForTerritory = ProPurchaseUtils.findPurchaseOptionsForTerritory(
player, defensePurchaseOptions, t, purchaseTerritory.getTerritory(), isBid);
purchaseOptionsForTerritory.addAll(airPurchaseOptions);

// Purchase necessary defenders
Expand Down Expand Up @@ -999,9 +999,8 @@ private void purchaseFactory(final Map<Territory, ProPurchaseTerritory> factoryP
}

// Determine units that can be produced in this territory
final List<ProPurchaseOption> purchaseOptionsForTerritory =
ProPurchaseUtils.findPurchaseOptionsForTerritory(player, purchaseOptions.getFactoryOptions(), maxTerritory,
isBid);
final List<ProPurchaseOption> purchaseOptionsForTerritory = ProPurchaseUtils
.findPurchaseOptionsForTerritory(player, purchaseOptions.getFactoryOptions(), maxTerritory, isBid);
resourceTracker.removeTempPurchase(maxPlacedOption);
ProPurchaseUtils.removeInvalidPurchaseOptions(player, startOfTurnData, purchaseOptionsForTerritory,
resourceTracker, 1, new ArrayList<>(), purchaseTerritories);
Expand Down Expand Up @@ -1172,7 +1171,7 @@ private void purchaseSeaAndAmphibUnits(final Map<Territory, ProPurchaseTerritory
// Determine sea and transport units that can be produced in this territory
final List<ProPurchaseOption> seaPurchaseOptionsForTerritory =
ProPurchaseUtils.findPurchaseOptionsForTerritory(player, purchaseOptions.getSeaDefenseOptions(), t,
isBid);
purchaseTerritory.getTerritory(), isBid);
seaPurchaseOptionsForTerritory.addAll(purchaseOptions.getAirOptions());

// Purchase enough sea defenders to hold territory
Expand Down Expand Up @@ -1316,8 +1315,8 @@ private void purchaseSeaAndAmphibUnits(final Map<Territory, ProPurchaseTerritory
}

// Determine sea and transport units that can be produced in this territory
final List<ProPurchaseOption> seaPurchaseOptionsForTerritory =
ProPurchaseUtils.findPurchaseOptionsForTerritory(player, purchaseOptions.getSeaDefenseOptions(), t, isBid);
final List<ProPurchaseOption> seaPurchaseOptionsForTerritory = ProPurchaseUtils.findPurchaseOptionsForTerritory(
player, purchaseOptions.getSeaDefenseOptions(), t, purchaseTerritory.getTerritory(), isBid);
seaPurchaseOptionsForTerritory.addAll(purchaseOptions.getAirOptions());
while (true) {

Expand Down Expand Up @@ -1379,9 +1378,8 @@ private void purchaseSeaAndAmphibUnits(final Map<Territory, ProPurchaseTerritory
final List<Unit> ownedLocalAmphibUnits = landTerritory.getUnits().getMatches(Matches.unitIsOwnedBy(player));

// Determine sea and transport units that can be produced in this territory
final List<ProPurchaseOption> seaTransportPurchaseOptionsForTerritory =
ProPurchaseUtils.findPurchaseOptionsForTerritory(player, purchaseOptions.getSeaTransportOptions(), t,
isBid);
final List<ProPurchaseOption> seaTransportPurchaseOptionsForTerritory = ProPurchaseUtils
.findPurchaseOptionsForTerritory(player, purchaseOptions.getSeaTransportOptions(), t, landTerritory, isBid);
final List<ProPurchaseOption> amphibPurchaseOptionsForTerritory =
ProPurchaseUtils.findPurchaseOptionsForTerritory(player, purchaseOptions.getLandOptions(), landTerritory,
isBid);
Expand Down Expand Up @@ -1890,15 +1888,16 @@ private void placeUnits(final List<ProPlaceTerritory> prioritizedTerritories,
}
}

private static void addUnitsToPlaceTerritory(final ProPlaceTerritory placeTerritory, final List<Unit> unitsToPlace,
private void addUnitsToPlaceTerritory(final ProPlaceTerritory placeTerritory, final List<Unit> unitsToPlace,
final Map<Territory, ProPurchaseTerritory> purchaseTerritories) {

// Add units to place territory
for (final ProPurchaseTerritory purchaseTerritory : purchaseTerritories.values()) {
for (final ProPlaceTerritory ppt : purchaseTerritory.getCanPlaceTerritories()) {

// If place territory is equal to the current place territory and has remaining production
if (placeTerritory.equals(ppt) && purchaseTerritory.getRemainingUnitProduction() > 0) {
if (placeTerritory.equals(ppt) && purchaseTerritory.getRemainingUnitProduction() > 0 && ProPurchaseUtils
.canUnitsBePlaced(unitsToPlace, player, ppt.getTerritory(), purchaseTerritory.getTerritory(), isBid)) {

// Place max number of units
final int numUnits = Math.min(purchaseTerritory.getRemainingUnitProduction(), unitsToPlace.size());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public ProPurchaseTerritory(final Territory territory, final GameData data, fina
canPlaceTerritories = new ArrayList<>();
canPlaceTerritories.add(new ProPlaceTerritory(territory));
if (!isBid) {
if (ProMatches.territoryHasInfraFactoryAndIsNotConqueredOwnedLand(player, data).test(territory)) {
if (ProMatches.territoryHasFactoryAndIsNotConqueredOwnedLand(player, data).test(territory)) {
for (final Territory t : data.getMap().getNeighbors(territory, Matches.territoryIsWater())) {
if (Properties.getWW2V2(data) || Properties.getUnitPlacementInEnemySeas(data)
|| !t.getUnits().anyMatch(Matches.enemyUnit(player, data))) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -216,14 +216,22 @@ static Predicate<Territory> territoryHasInfraFactoryAndIsOwnedByPlayersOrCantBeH
return territoryHasInfraFactoryAndIsLand().and(enemyOrOwnedCantBeHeld);
}

public static Predicate<Territory> territoryHasInfraFactoryAndIsNotConqueredOwnedLand(final PlayerID player,
public static Predicate<Territory> territoryHasFactoryAndIsNotConqueredOwnedLand(final PlayerID player,
final GameData data) {
return territoryIsNotConqueredOwnedLand(player, data).and(territoryHasInfraFactoryAndIsOwnedLand(player));
return territoryIsNotConqueredOwnedLand(player, data).and(territoryHasFactoryAndIsOwnedLand(player));
}

public static Predicate<Territory> territoryHasNonMobileInfraFactoryAndIsNotConqueredOwnedLand(final PlayerID player,
private static Predicate<Territory> territoryHasFactoryAndIsOwnedLand(final PlayerID player) {
final Predicate<Unit> factoryMatch = Matches.unitIsOwnedBy(player)
.and(Matches.unitCanProduceUnits());
return Matches.isTerritoryOwnedBy(player)
.and(Matches.territoryIsLand())
.and(Matches.territoryHasUnitsThatMatch(factoryMatch));
}

public static Predicate<Territory> territoryHasNonMobileFactoryAndIsNotConqueredOwnedLand(final PlayerID player,
final GameData data) {
return territoryHasNonMobileInfraFactory().and(territoryHasInfraFactoryAndIsNotConqueredOwnedLand(player, data));
return territoryHasNonMobileInfraFactory().and(territoryHasFactoryAndIsNotConqueredOwnedLand(player, data));
}

private static Predicate<Territory> territoryHasNonMobileInfraFactory() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,31 +46,47 @@ public class ProPurchaseUtils {

public static List<ProPurchaseOption> findPurchaseOptionsForTerritory(final PlayerID player,
final List<ProPurchaseOption> purchaseOptions, final Territory t, final boolean isBid) {
return findPurchaseOptionsForTerritory(player, purchaseOptions, t, t, isBid);
}

public static List<ProPurchaseOption> findPurchaseOptionsForTerritory(final PlayerID player,
final List<ProPurchaseOption> purchaseOptions, final Territory t, final Territory factoryTerritory,
final boolean isBid) {
final List<ProPurchaseOption> result = new ArrayList<>();
for (final ProPurchaseOption ppo : purchaseOptions) {
if (canTerritoryUsePurchaseOption(player, ppo, t, isBid)) {
if (canTerritoryUsePurchaseOption(player, ppo, t, factoryTerritory, isBid)) {
result.add(ppo);
}
}
return result;
}

private static boolean canTerritoryUsePurchaseOption(final PlayerID player, final ProPurchaseOption ppo,
final Territory t, final boolean isBid) {
final Territory t, final Territory factoryTerritory, final boolean isBid) {
if (ppo == null) {
return false;
}
final List<Unit> units = ppo.getUnitType().create(ppo.getQuantity(), player, true);
return canUnitsBePlaced(units, player, t, isBid);
return canUnitsBePlaced(units, player, t, factoryTerritory, isBid);
}

public static boolean canUnitsBePlaced(final List<Unit> units, final PlayerID player, final Territory t,
final boolean isBid) {
final GameData data = ProData.getData();
return canUnitsBePlaced(units, player, t, t, isBid);
}

/**
* Check if units can be placed in given territory by specified factory.
*/
public static boolean canUnitsBePlaced(final List<Unit> units, final PlayerID player, final Territory t,
final Territory factoryTerritory, final boolean isBid) {
final GameData data = player.getData();
AbstractPlaceDelegate placeDelegate = (AbstractPlaceDelegate) data.getDelegateList().getDelegate("place");
if (isBid) {
placeDelegate = (AbstractPlaceDelegate) data.getDelegateList().getDelegate("placeBid");
} else if (!t.equals(factoryTerritory) && !units.stream().allMatch(Matches
.unitWhichRequiresUnitsHasRequiredUnitsInList(placeDelegate.unitsAtStartOfStepInTerritory(factoryTerritory)))) {
return false;
}
final IDelegateBridge bridge = new ProDummyDelegateBridge(ProData.getProAi(), player, data);
placeDelegate.setDelegateBridgeAndPlayer(bridge);
Expand Down Expand Up @@ -237,7 +253,7 @@ public static Map<Territory, ProPurchaseTerritory> findPurchaseTerritories(final
ownedAndNotConqueredFactoryTerritories = data.getMap().getTerritoriesOwnedBy(player);
} else {
ownedAndNotConqueredFactoryTerritories = CollectionUtils.getMatches(data.getMap().getTerritories(),
ProMatches.territoryHasInfraFactoryAndIsNotConqueredOwnedLand(player, data));
ProMatches.territoryHasFactoryAndIsNotConqueredOwnedLand(player, data));
}
ownedAndNotConqueredFactoryTerritories = CollectionUtils.getMatches(ownedAndNotConqueredFactoryTerritories,
ProMatches.territoryCanMoveLandUnits(player, data, false));
Expand Down Expand Up @@ -282,7 +298,7 @@ private static PlayerID getOriginalFactoryOwner(final Territory territory, final
if (factoryUnits.size() == 0) {
throw new IllegalStateException("No factory in territory:" + territory);
}
for (Unit factory2 : factoryUnits) {
for (final Unit factory2 : factoryUnits) {
if (player.equals(OriginalOwnerTracker.getOriginalOwner(factory2))) {
return OriginalOwnerTracker.getOriginalOwner(factory2);
}
Expand Down

0 comments on commit 778591f

Please sign in to comment.