Search in sources :

Example 91 with Territory

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

the class ProTechAi method findUnitTerr.

/**
 * Return Territories containing any unit depending on unitCondition
 * Differs from findCertainShips because it doesn't require the units be owned.
 */
private static List<Territory> findUnitTerr(final GameData data, final Predicate<Unit> unitCondition) {
    // Return territories containing a certain unit or set of Units
    final List<Territory> shipTerr = new ArrayList<>();
    final Collection<Territory> neighbors = data.getMap().getTerritories();
    for (final Territory t2 : neighbors) {
        if (t2.getUnits().anyMatch(unitCondition)) {
            shipTerr.add(t2);
        }
    }
    return shipTerr;
}
Also used : Territory(games.strategy.engine.data.Territory) ArrayList(java.util.ArrayList)

Example 92 with Territory

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

the class ProTechAi method getNeighboringLandTerritories.

/**
 * All Allied Territories which neighbor a territory
 * This duplicates getNeighbors(check, Matches.isTerritoryAllied(player, data))
 */
private static List<Territory> getNeighboringLandTerritories(final GameData data, final PlayerID player, final Territory check) {
    final List<Territory> territories = new ArrayList<>();
    final List<Territory> checkList = getExactNeighbors(check, data);
    for (final Territory t : checkList) {
        if (Matches.isTerritoryAllied(player, data).test(t) && Matches.territoryIsNotImpassableToLandUnits(player, data).test(t)) {
            territories.add(t);
        }
    }
    return territories;
}
Also used : Territory(games.strategy.engine.data.Territory) ArrayList(java.util.ArrayList)

Example 93 with Territory

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

the class ProCombatMoveAi method prioritizeAttackOptions.

private List<ProTerritory> prioritizeAttackOptions(final PlayerID player, final List<ProTerritory> attackOptions) {
    ProLogger.info("Prioritizing territories to try to attack");
    // Calculate value of attacking territory
    for (final Iterator<ProTerritory> it = attackOptions.iterator(); it.hasNext(); ) {
        final ProTerritory patd = it.next();
        final Territory t = patd.getTerritory();
        // Determine territory attack properties
        final int isLand = !t.isWater() ? 1 : 0;
        final int isNeutral = (!t.isWater() && t.getOwner().isNull()) ? 1 : 0;
        final int isCanHold = patd.isCanHold() ? 1 : 0;
        final int isAmphib = patd.isNeedAmphibUnits() ? 1 : 0;
        final List<Unit> defendingUnits = CollectionUtils.getMatches(patd.getMaxEnemyDefenders(player, data), ProMatches.unitIsEnemyAndNotInfa(player, data));
        final int isEmptyLand = (defendingUnits.isEmpty() && !patd.isNeedAmphibUnits()) ? 1 : 0;
        final boolean isAdjacentToMyCapital = !data.getMap().getNeighbors(t, Matches.territoryIs(ProData.myCapital)).isEmpty();
        final int isNotNeutralAdjacentToMyCapital = (isAdjacentToMyCapital && ProMatches.territoryIsEnemyNotNeutralLand(player, data).test(t)) ? 1 : 0;
        final int isFactory = ProMatches.territoryHasInfraFactoryAndIsLand().test(t) ? 1 : 0;
        final int isFfa = ProUtils.isFfa(data, player) ? 1 : 0;
        // Determine production value and if it is an enemy capital
        int production = 0;
        int isEnemyCapital = 0;
        final TerritoryAttachment ta = TerritoryAttachment.get(t);
        if (ta != null) {
            production = ta.getProduction();
            if (ta.isCapital()) {
                isEnemyCapital = 1;
            }
        }
        // Calculate attack value for prioritization
        double tuvSwing = patd.getMaxBattleResult().getTuvSwing();
        if (isFfa == 1 && tuvSwing > 0) {
            tuvSwing *= 0.5;
        }
        final double territoryValue = (1 + isLand + isCanHold * (1 + 2 * isFfa)) * (1 + isEmptyLand) * (1 + isFactory) * (1 - 0.5 * isAmphib) * production;
        double attackValue = (tuvSwing + territoryValue) * (1 + 4 * isEnemyCapital) * (1 + 2 * isNotNeutralAdjacentToMyCapital) * (1 - 0.9 * isNeutral);
        // Check if a negative value neutral territory should be attacked
        if (attackValue <= 0 && !patd.isNeedAmphibUnits() && !t.isWater() && t.getOwner().isNull()) {
            // Determine enemy neighbor territory production value for neutral land territories
            double nearbyEnemyValue = 0;
            final List<Territory> cantReachEnemyTerritories = new ArrayList<>();
            final Set<Territory> nearbyTerritories = data.getMap().getNeighbors(t, ProMatches.territoryCanMoveLandUnits(player, data, true));
            final List<Territory> nearbyEnemyTerritories = CollectionUtils.getMatches(nearbyTerritories, Matches.isTerritoryEnemy(player, data));
            final List<Territory> nearbyTerritoriesWithOwnedUnits = CollectionUtils.getMatches(nearbyTerritories, Matches.territoryHasUnitsOwnedBy(player));
            for (final Territory nearbyEnemyTerritory : nearbyEnemyTerritories) {
                boolean allAlliedNeighborsHaveRoute = true;
                for (final Territory nearbyAlliedTerritory : nearbyTerritoriesWithOwnedUnits) {
                    final int distance = data.getMap().getDistance_IgnoreEndForCondition(nearbyAlliedTerritory, nearbyEnemyTerritory, ProMatches.territoryIsEnemyNotNeutralOrAllied(player, data));
                    if (distance < 0 || distance > 2) {
                        allAlliedNeighborsHaveRoute = false;
                        break;
                    }
                }
                if (!allAlliedNeighborsHaveRoute) {
                    final double value = ProTerritoryValueUtils.findTerritoryAttackValue(player, nearbyEnemyTerritory);
                    if (value > 0) {
                        nearbyEnemyValue += value;
                    }
                    cantReachEnemyTerritories.add(nearbyEnemyTerritory);
                }
            }
            ProLogger.debug(t.getName() + " calculated nearby enemy value=" + nearbyEnemyValue + " from " + cantReachEnemyTerritories);
            if (nearbyEnemyValue > 0) {
                ProLogger.trace(t.getName() + " updating negative neutral attack value=" + attackValue);
                attackValue = nearbyEnemyValue * .001 / (1 - attackValue);
            } else {
                // Check if overwhelming attack strength (more than 5 times)
                final double strengthDifference = ProBattleUtils.estimateStrengthDifference(t, patd.getMaxUnits(), patd.getMaxEnemyDefenders(player, data));
                ProLogger.debug(t.getName() + " calculated strengthDifference=" + strengthDifference);
                if (strengthDifference > 500) {
                    ProLogger.trace(t.getName() + " updating negative neutral attack value=" + attackValue);
                    attackValue = strengthDifference * .00001 / (1 - attackValue);
                }
            }
        }
        // Remove negative value territories
        patd.setValue(attackValue);
        if (attackValue <= 0 || (isDefensive && attackValue <= 8 && data.getMap().getDistance(ProData.myCapital, t) <= 3)) {
            ProLogger.debug("Removing territory that has a negative attack value: " + t.getName() + ", AttackValue=" + patd.getValue());
            it.remove();
        }
    }
    // Sort attack territories by value
    attackOptions.sort(Comparator.comparingDouble(ProTerritory::getValue));
    // Log prioritized territories
    for (final ProTerritory patd : attackOptions) {
        ProLogger.debug("AttackValue=" + patd.getValue() + ", TUVSwing=" + patd.getMaxBattleResult().getTuvSwing() + ", isAmphib=" + patd.isNeedAmphibUnits() + ", " + patd.getTerritory().getName());
    }
    return attackOptions;
}
Also used : Territory(games.strategy.engine.data.Territory) ProTerritory(games.strategy.triplea.ai.pro.data.ProTerritory) ProTerritory(games.strategy.triplea.ai.pro.data.ProTerritory) TerritoryAttachment(games.strategy.triplea.attachments.TerritoryAttachment) ArrayList(java.util.ArrayList) TripleAUnit(games.strategy.triplea.TripleAUnit) Unit(games.strategy.engine.data.Unit)

Example 94 with Territory

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

the class ProCombatMoveAi method determineTerritoriesToAttack.

private void determineTerritoriesToAttack(final List<ProTerritory> prioritizedTerritories) {
    ProLogger.info("Determine which territories to attack");
    // Assign units to territories by prioritization
    int numToAttack = Math.min(1, prioritizedTerritories.size());
    boolean haveRemovedAllAmphibTerritories = false;
    while (true) {
        final List<ProTerritory> territoriesToTryToAttack = prioritizedTerritories.subList(0, numToAttack);
        ProLogger.debug("Current number of territories: " + numToAttack);
        tryToAttackTerritories(territoriesToTryToAttack, new ArrayList<>());
        // Determine if all attacks are successful
        boolean areSuccessful = true;
        for (final ProTerritory patd : territoriesToTryToAttack) {
            final Territory t = patd.getTerritory();
            if (patd.getBattleResult() == null) {
                patd.setBattleResult(calc.estimateAttackBattleResults(t, patd.getUnits(), patd.getMaxEnemyDefenders(player, data), patd.getBombardTerritoryMap().keySet()));
            }
            ProLogger.trace(patd.getResultString() + " with attackers: " + patd.getUnits());
            final double estimate = ProBattleUtils.estimateStrengthDifference(t, patd.getUnits(), patd.getMaxEnemyDefenders(player, data));
            final ProBattleResult result = patd.getBattleResult();
            if (!patd.isStrafing() && estimate < patd.getStrengthEstimate() && (result.getWinPercentage() < ProData.minWinPercentage || !result.isHasLandUnitRemaining())) {
                areSuccessful = false;
            }
        }
        // Determine whether to try more territories, remove a territory, or end
        if (areSuccessful) {
            for (final ProTerritory patd : territoriesToTryToAttack) {
                patd.setCanAttack(true);
                final double estimate = ProBattleUtils.estimateStrengthDifference(patd.getTerritory(), patd.getUnits(), patd.getMaxEnemyDefenders(player, data));
                if (estimate < patd.getStrengthEstimate()) {
                    patd.setStrengthEstimate(estimate);
                }
            }
            // If already used all transports then remove any remaining amphib territories
            if (!haveRemovedAllAmphibTerritories) {
                if (territoryManager.haveUsedAllAttackTransports()) {
                    final List<ProTerritory> amphibTerritoriesToRemove = new ArrayList<>();
                    for (int i = numToAttack; i < prioritizedTerritories.size(); i++) {
                        if (prioritizedTerritories.get(i).isNeedAmphibUnits()) {
                            amphibTerritoriesToRemove.add(prioritizedTerritories.get(i));
                            ProLogger.debug("Removing amphib territory since already used all transports: " + prioritizedTerritories.get(i).getTerritory().getName());
                        }
                    }
                    prioritizedTerritories.removeAll(amphibTerritoriesToRemove);
                    haveRemovedAllAmphibTerritories = true;
                }
            }
            // Can attack all territories in list so end
            numToAttack++;
            if (numToAttack > prioritizedTerritories.size()) {
                break;
            }
        } else {
            ProLogger.debug("Removing territory: " + prioritizedTerritories.get(numToAttack - 1).getTerritory().getName());
            prioritizedTerritories.remove(numToAttack - 1);
            if (numToAttack > prioritizedTerritories.size()) {
                numToAttack--;
            }
        }
    }
    ProLogger.debug("Final number of territories: " + (numToAttack - 1));
}
Also used : Territory(games.strategy.engine.data.Territory) ProTerritory(games.strategy.triplea.ai.pro.data.ProTerritory) ProTerritory(games.strategy.triplea.ai.pro.data.ProTerritory) ArrayList(java.util.ArrayList) ProBattleResult(games.strategy.triplea.ai.pro.data.ProBattleResult)

Example 95 with Territory

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

the class ProCombatMoveAi method removeAttacksUntilCapitalCanBeHeld.

private void removeAttacksUntilCapitalCanBeHeld(final List<ProTerritory> prioritizedTerritories, final List<ProPurchaseOption> landPurchaseOptions) {
    ProLogger.info("Check capital defenses after attack moves");
    final Map<Territory, ProTerritory> attackMap = territoryManager.getAttackOptions().getTerritoryMap();
    final Territory myCapital = ProData.myCapital;
    // 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)) {
        placeUnits.addAll(ProPurchaseUtils.findMaxPurchaseDefenders(player, myCapital, landPurchaseOptions));
    }
    // Remove attack until capital can be defended
    while (true) {
        if (prioritizedTerritories.isEmpty()) {
            break;
        }
        // Determine max enemy counter attack units
        final List<Territory> territoriesToAttack = new ArrayList<>();
        for (final ProTerritory t : prioritizedTerritories) {
            territoriesToAttack.add(t.getTerritory());
        }
        ProLogger.trace("Remaining territories to attack=" + territoriesToAttack);
        final List<Territory> territoriesToCheck = new ArrayList<>();
        territoriesToCheck.add(myCapital);
        territoryManager.populateEnemyAttackOptions(territoriesToAttack, territoriesToCheck);
        final ProOtherMoveOptions enemyAttackOptions = territoryManager.getEnemyAttackOptions();
        if (enemyAttackOptions.getMax(myCapital) == null) {
            break;
        }
        // Find max remaining defenders
        final Set<Territory> territoriesAdjacentToCapital = data.getMap().getNeighbors(myCapital, Matches.territoryIsLand());
        final List<Unit> defenders = myCapital.getUnits().getMatches(Matches.isUnitAllied(player, data));
        defenders.addAll(placeUnits);
        for (final Territory t : territoriesAdjacentToCapital) {
            defenders.addAll(t.getUnits().getMatches(ProMatches.unitCanBeMovedAndIsOwnedLand(player, false)));
        }
        for (final ProTerritory t : attackMap.values()) {
            defenders.removeAll(t.getUnits());
        }
        // Determine counter attack results to see if I can hold it
        final Set<Unit> enemyAttackingUnits = new HashSet<>(enemyAttackOptions.getMax(myCapital).getMaxUnits());
        enemyAttackingUnits.addAll(enemyAttackOptions.getMax(myCapital).getMaxAmphibUnits());
        final ProBattleResult result = calc.estimateDefendBattleResults(myCapital, new ArrayList<>(enemyAttackingUnits), defenders, enemyAttackOptions.getMax(myCapital).getMaxBombardUnits());
        ProLogger.trace("Current capital result hasLandUnitRemaining=" + result.isHasLandUnitRemaining() + ", TUVSwing=" + result.getTuvSwing() + ", defenders=" + defenders.size() + ", attackers=" + enemyAttackingUnits.size());
        // Determine attack that uses the most units per value from capital and remove it
        if (result.isHasLandUnitRemaining()) {
            double maxUnitsNearCapitalPerValue = 0.0;
            Territory maxTerritory = null;
            final Set<Territory> territoriesNearCapital = data.getMap().getNeighbors(myCapital, Matches.territoryIsLand());
            territoriesNearCapital.add(myCapital);
            for (final Territory t : attackMap.keySet()) {
                int unitsNearCapital = 0;
                for (final Unit u : attackMap.get(t).getUnits()) {
                    if (territoriesNearCapital.contains(ProData.unitTerritoryMap.get(u))) {
                        unitsNearCapital++;
                    }
                }
                final double unitsNearCapitalPerValue = unitsNearCapital / attackMap.get(t).getValue();
                ProLogger.trace(t.getName() + " has unit near capital per value: " + unitsNearCapitalPerValue);
                if (unitsNearCapitalPerValue > maxUnitsNearCapitalPerValue) {
                    maxUnitsNearCapitalPerValue = unitsNearCapitalPerValue;
                    maxTerritory = t;
                }
            }
            if (maxTerritory != null) {
                prioritizedTerritories.remove(attackMap.get(maxTerritory));
                attackMap.get(maxTerritory).getUnits().clear();
                attackMap.get(maxTerritory).getAmphibAttackMap().clear();
                attackMap.get(maxTerritory).setBattleResult(null);
                ProLogger.debug("Removing territory to try to hold capital: " + maxTerritory.getName());
            } else {
                break;
            }
        } else {
            ProLogger.debug("Can hold capital: " + myCapital.getName());
            break;
        }
    }
}
Also used : Territory(games.strategy.engine.data.Territory) ProTerritory(games.strategy.triplea.ai.pro.data.ProTerritory) ProTerritory(games.strategy.triplea.ai.pro.data.ProTerritory) ArrayList(java.util.ArrayList) ProBattleResult(games.strategy.triplea.ai.pro.data.ProBattleResult) TripleAUnit(games.strategy.triplea.TripleAUnit) Unit(games.strategy.engine.data.Unit) ProOtherMoveOptions(games.strategy.triplea.ai.pro.data.ProOtherMoveOptions) HashSet(java.util.HashSet)

Aggregations

Territory (games.strategy.engine.data.Territory)420 Unit (games.strategy.engine.data.Unit)254 TripleAUnit (games.strategy.triplea.TripleAUnit)195 PlayerID (games.strategy.engine.data.PlayerID)164 ArrayList (java.util.ArrayList)160 Test (org.junit.jupiter.api.Test)140 Route (games.strategy.engine.data.Route)137 ITestDelegateBridge (games.strategy.engine.data.ITestDelegateBridge)118 GameData (games.strategy.engine.data.GameData)94 HashSet (java.util.HashSet)87 UnitType (games.strategy.engine.data.UnitType)65 HashMap (java.util.HashMap)65 ScriptedRandomSource (games.strategy.engine.random.ScriptedRandomSource)50 Collection (java.util.Collection)47 IntegerMap (games.strategy.util.IntegerMap)45 Set (java.util.Set)41 ProTerritory (games.strategy.triplea.ai.pro.data.ProTerritory)39 TerritoryAttachment (games.strategy.triplea.attachments.TerritoryAttachment)37 List (java.util.List)36 ProPurchaseTerritory (games.strategy.triplea.ai.pro.data.ProPurchaseTerritory)34