Skip to content

Commit

Permalink
Clean up some pro AI code related to purchasing. No logic changes. (#…
Browse files Browse the repository at this point in the history
…10434)

Clean up some pro AI code related to purchasing. No logic changes.
Some efficiency improvements to the logic by avoiding unnecessary operations, by removing collection copies and moving code out of loop bodies.
  • Loading branch information
asvitkine authored May 11, 2022
1 parent 92094f5 commit 0a86a72
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 124 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,7 @@ Map<Territory, ProTerritory> doCombatMove(final IMoveDelegate moveDel) {
}
}
possibleTransportTerritories.addAll(clearedTerritories);
territoryManager.populateEnemyAttackOptions(
clearedTerritories, new ArrayList<>(possibleTransportTerritories));
territoryManager.populateEnemyAttackOptions(clearedTerritories, possibleTransportTerritories);
determineTerritoriesThatCanBeHeld(attackOptions, clearedTerritories);
removeTerritoriesThatArentWorthAttacking(attackOptions);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,6 @@ void repair(
*/
Map<Territory, ProPurchaseTerritory> bid(
final int pus, final IPurchaseDelegate purchaseDelegate, final GameState startOfTurnData) {

// Current data fields
data = proData.getData();
this.startOfTurnData = startOfTurnData;
Expand All @@ -162,7 +161,6 @@ Map<Territory, ProPurchaseTerritory> bid(

int previousNumUnits = 0;
while (true) {

// Determine max enemy attack units and current allied defenders
territoryManager.populateEnemyAttackOptions(
new ArrayList<>(), new ArrayList<>(purchaseTerritories.keySet()));
Expand Down Expand Up @@ -257,7 +255,6 @@ Map<Territory, ProPurchaseTerritory> bid(

Map<Territory, ProPurchaseTerritory> purchase(
final IPurchaseDelegate purchaseDelegate, final GameState startOfTurnData) {

// Current data fields
data = proData.getData();
this.startOfTurnData = startOfTurnData;
Expand All @@ -279,15 +276,14 @@ Map<Territory, ProPurchaseTerritory> purchase(
new HashSet<>(
CollectionUtils.getMatches(
data.getMap().getTerritoriesOwnedBy(player), Matches.territoryIsLand()));
for (final Territory t : purchaseTerritories.keySet()) {
for (final ProPlaceTerritory ppt : purchaseTerritories.get(t).getCanPlaceTerritories()) {
for (final ProPurchaseTerritory t : purchaseTerritories.values()) {
for (final ProPlaceTerritory ppt : t.getCanPlaceTerritories()) {
placeTerritories.add(ppt.getTerritory());
}
}

// Determine max enemy attack units and current allied defenders
territoryManager.populateEnemyAttackOptions(
new ArrayList<>(), new ArrayList<>(placeTerritories));
territoryManager.populateEnemyAttackOptions(List.of(), placeTerritories);
findDefendersInPlaceTerritories(purchaseTerritories);

// Prioritize land territories that need defended and purchase additional defenders
Expand Down Expand Up @@ -660,7 +656,6 @@ private void purchaseDefenders(
final List<ProPurchaseOption> zeroMoveDefensePurchaseOptions,
final List<ProPurchaseOption> airPurchaseOptions,
final boolean isLand) {

if (resourceTracker.isEmpty()) {
return;
}
Expand Down Expand Up @@ -696,20 +691,17 @@ private void purchaseDefenders(
+ unusedLocalCarrierCapacity);

// Determine if need destroyer
boolean needDestroyer = false;
if (enemyAttackOptions.getMax(t).getMaxUnits().stream()
.anyMatch(Matches.unitHasSubBattleAbilities())
&& ownedLocalUnits.stream().noneMatch(Matches.unitIsDestroyer())) {
needDestroyer = true;
}
boolean needDestroyer =
enemyAttackOptions.getMax(t).getMaxUnits().stream()
.anyMatch(Matches.unitHasSubBattleAbilities())
&& ownedLocalUnits.stream().noneMatch(Matches.unitIsDestroyer());

// Find all purchase territories for place territory
final List<Unit> unitsToPlace = new ArrayList<>();
ProBattleResult finalResult = new ProBattleResult();
final List<ProPurchaseTerritory> selectedPurchaseTerritories =
getPurchaseTerritories(placeTerritory, purchaseTerritories);
for (final ProPurchaseTerritory purchaseTerritory : selectedPurchaseTerritories) {

// Check remaining production
int remainingUnitProduction = purchaseTerritory.getRemainingUnitProduction();
int remainingConstructions =
Expand Down Expand Up @@ -741,7 +733,6 @@ private void purchaseDefenders(

// Purchase necessary defenders
while (true) {

// Select purchase option
ProPurchaseValidationUtils.removeInvalidPurchaseOptions(
player,
Expand Down Expand Up @@ -1020,17 +1011,14 @@ private void purchaseLandUnits(

// Loop through prioritized territories and purchase land units
final Set<Territory> territoriesToCheck = new HashSet<>();
final Predicate<Territory> canMoveLandUnits =
ProMatches.territoryCanPotentiallyMoveLandUnits(player, data.getProperties());
final Predicate<Territory> isEnemyTerritory =
Matches.isTerritoryOwnedByAnyOf(ProUtils.getEnemyPlayers(player));
for (final ProPlaceTerritory placeTerritory : prioritizedLandTerritories) {
final Set<Territory> landTerritories =
data.getMap()
.getNeighbors(
placeTerritory.getTerritory(),
9,
ProMatches.territoryCanPotentiallyMoveLandUnits(player, data.getProperties()));
final List<Territory> enemyLandTerritories =
CollectionUtils.getMatches(
landTerritories, Matches.isTerritoryOwnedByAnyOf(ProUtils.getEnemyPlayers(player)));
territoriesToCheck.addAll(enemyLandTerritories);
data.getMap().getNeighbors(placeTerritory.getTerritory(), 9, canMoveLandUnits);
territoriesToCheck.addAll(CollectionUtils.getMatches(landTerritories, isEnemyTerritory));
}
final Map<Territory, Double> territoryValueMap =
ProTerritoryValueUtils.findTerritoryValues(
Expand Down Expand Up @@ -1081,7 +1069,7 @@ private void purchaseLandUnits(
for (final Iterator<Unit> it = unplacedUnits.iterator(); it.hasNext(); ) {
final Unit u = it.next();
if (remainingUnitProduction > 0
&& ProPurchaseValidationUtils.canUnitsBePlaced(proData, List.of(u), player, t, isBid)) {
&& ProPurchaseValidationUtils.canUnitBePlaced(proData, u, player, t, isBid)) {
remainingUnitProduction--;
unitsToPlace.add(u);
it.remove();
Expand All @@ -1094,7 +1082,6 @@ private void purchaseLandUnits(
double attackAndDefenseDifference = 0;
boolean selectFodderUnit = true;
while (true) {

// Remove options that cost too much PUs or production
ProPurchaseValidationUtils.removeInvalidPurchaseOptions(
player,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,8 @@ public void populateDefenseOptions(final List<Territory> clearedTerritories) {
}

public void populateEnemyAttackOptions(
final List<Territory> clearedTerritories, final List<Territory> territoriesToCheck) {
final Collection<Territory> clearedTerritories,
final Collection<Territory> territoriesToCheck) {
enemyAttackOptions =
findEnemyAttackOptions(proData, player, clearedTerritories, territoriesToCheck);
}
Expand Down Expand Up @@ -415,7 +416,7 @@ private static void findAttackOptions(
final List<ProTransport> transportMapList,
final List<Territory> enemyTerritories,
final List<Territory> alliedTerritories,
final List<Territory> territoriesToCheck,
final Collection<Territory> territoriesToCheck,
final boolean isCheckingEnemyAttacks,
final boolean isIgnoringRelationships) {
final GameState data = proData.getData();
Expand Down Expand Up @@ -534,8 +535,8 @@ private ProOtherMoveOptions findAlliedAttackOptions(final GamePlayer player) {
private static ProOtherMoveOptions findEnemyAttackOptions(
final ProData proData,
final GamePlayer player,
final List<Territory> clearedTerritories,
final List<Territory> territoriesToCheck) {
final Collection<Territory> clearedTerritories,
final Collection<Territory> territoriesToCheck) {
final GameState data = proData.getData();

// Get enemy players in order of turn
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@
import games.strategy.triplea.attachments.TerritoryAttachment;
import games.strategy.triplea.delegate.AbstractPlaceDelegate;
import games.strategy.triplea.delegate.Matches;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import lombok.experimental.UtilityClass;
import org.triplea.java.collections.CollectionUtils;

Expand Down Expand Up @@ -49,38 +49,22 @@ public static List<ProPurchaseOption> findPurchaseOptionsForTerritory(
final Territory t,
final Territory factoryTerritory,
final boolean isBid) {
final List<ProPurchaseOption> result = new ArrayList<>();
for (final ProPurchaseOption ppo : purchaseOptions) {
if (ProPurchaseValidationUtils.canTerritoryUsePurchaseOption(
proData, player, ppo, t, factoryTerritory, isBid)) {
result.add(ppo);
}
}
return result;
final Predicate<ProPurchaseOption> canUsePurchaseOption =
ppo -> {
final List<Unit> units = ppo.getUnitType().createTemp(ppo.getQuantity(), player);
return ProPurchaseValidationUtils.canUnitsBePlaced(
proData, units, player, t, factoryTerritory, isBid);
};
return purchaseOptions.stream().filter(canUsePurchaseOption).collect(Collectors.toList());
}

private static boolean canTerritoryUsePurchaseOption(
public static boolean canUnitBePlaced(
final ProData proData,
final GamePlayer player,
final ProPurchaseOption ppo,
final Territory t,
final Territory factoryTerritory,
final boolean isBid) {
if (ppo == null) {
return false;
}
final List<Unit> units = ppo.getUnitType().createTemp(ppo.getQuantity(), player);
return ProPurchaseValidationUtils.canUnitsBePlaced(
proData, units, player, t, factoryTerritory, isBid);
}

public static boolean canUnitsBePlaced(
final ProData proData,
final List<Unit> units,
final Unit unit,
final GamePlayer player,
final Territory t,
final boolean isBid) {
return ProPurchaseValidationUtils.canUnitsBePlaced(proData, units, player, t, t, isBid);
return ProPurchaseValidationUtils.canUnitsBePlaced(proData, List.of(unit), player, t, t, isBid);
}

/** Check if units can be placed in given territory by specified factory. */
Expand Down
Loading

0 comments on commit 0a86a72

Please sign in to comment.