Search in sources :

Example 21 with TerritoryAttachment

use of games.strategy.triplea.attachments.TerritoryAttachment in project triplea by triplea-game.

the class ProSimulateTurnUtils method checkIfCapturedTerritoryIsAlliedCapital.

private static boolean checkIfCapturedTerritoryIsAlliedCapital(final Territory t, final GameData data, final PlayerID player, final IDelegateBridge delegateBridge) {
    final PlayerID terrOrigOwner = OriginalOwnerTracker.getOriginalOwner(t);
    final RelationshipTracker relationshipTracker = data.getRelationshipTracker();
    final TerritoryAttachment ta = TerritoryAttachment.get(t);
    if (ta != null && ta.getCapital() != null && terrOrigOwner != null && TerritoryAttachment.getAllCapitals(terrOrigOwner, data).contains(t) && relationshipTracker.isAllied(terrOrigOwner, player)) {
        // Give capital and any allied territories back to original owner
        final Collection<Territory> originallyOwned = OriginalOwnerTracker.getOriginallyOwned(data, terrOrigOwner);
        final List<Territory> friendlyTerritories = CollectionUtils.getMatches(originallyOwned, Matches.isTerritoryAllied(terrOrigOwner, data));
        friendlyTerritories.add(t);
        for (final Territory item : friendlyTerritories) {
            if (item.getOwner() == terrOrigOwner) {
                continue;
            }
            final Change takeOverFriendlyTerritories = ChangeFactory.changeOwner(item, terrOrigOwner);
            delegateBridge.addChange(takeOverFriendlyTerritories);
            final Collection<Unit> units = CollectionUtils.getMatches(item.getUnits().getUnits(), Matches.unitIsInfrastructure());
            if (!units.isEmpty()) {
                final Change takeOverNonComUnits = ChangeFactory.changeOwner(units, terrOrigOwner, t);
                delegateBridge.addChange(takeOverNonComUnits);
            }
        }
        return true;
    }
    return false;
}
Also used : PlayerID(games.strategy.engine.data.PlayerID) Territory(games.strategy.engine.data.Territory) ProTerritory(games.strategy.triplea.ai.pro.data.ProTerritory) TerritoryAttachment(games.strategy.triplea.attachments.TerritoryAttachment) RelationshipTracker(games.strategy.engine.data.RelationshipTracker) Change(games.strategy.engine.data.Change) Unit(games.strategy.engine.data.Unit)

Example 22 with TerritoryAttachment

use of games.strategy.triplea.attachments.TerritoryAttachment in project triplea by triplea-game.

the class ProPurchaseUtils method getUnitProduction.

private static int getUnitProduction(final Territory territory, final GameData data, final PlayerID player) {
    final Predicate<Unit> factoryMatch = Matches.unitIsOwnedAndIsFactoryOrCanProduceUnits(player).and(Matches.unitIsBeingTransported().negate()).and((territory.isWater() ? Matches.unitIsLand() : Matches.unitIsSea()).negate());
    final Collection<Unit> factoryUnits = territory.getUnits().getMatches(factoryMatch);
    final TerritoryAttachment ta = TerritoryAttachment.get(territory);
    final boolean originalFactory = (ta != null && ta.getOriginalFactory());
    final boolean playerIsOriginalOwner = factoryUnits.size() > 0 && player.equals(getOriginalFactoryOwner(territory, player));
    final RulesAttachment ra = player.getRulesAttachment();
    if (originalFactory && playerIsOriginalOwner) {
        if (ra != null && ra.getMaxPlacePerTerritory() != -1) {
            return Math.max(0, ra.getMaxPlacePerTerritory());
        }
        return Integer.MAX_VALUE;
    }
    if (ra != null && ra.getPlacementAnyTerritory()) {
        return Integer.MAX_VALUE;
    }
    return TripleAUnit.getProductionPotentialOfTerritory(territory.getUnits().getUnits(), territory, player, data, true, true);
}
Also used : TerritoryAttachment(games.strategy.triplea.attachments.TerritoryAttachment) TripleAUnit(games.strategy.triplea.TripleAUnit) Unit(games.strategy.engine.data.Unit) RulesAttachment(games.strategy.triplea.attachments.RulesAttachment)

Example 23 with TerritoryAttachment

use of games.strategy.triplea.attachments.TerritoryAttachment in project triplea by triplea-game.

the class AbstractEndTurnDelegate method changeUnitOwnership.

private static void changeUnitOwnership(final IDelegateBridge bridge) {
    final PlayerID player = bridge.getPlayerId();
    final PlayerAttachment pa = PlayerAttachment.get(player);
    final Collection<PlayerID> possibleNewOwners = pa.getGiveUnitControl();
    final Collection<Territory> territories = bridge.getData().getMap().getTerritories();
    final CompositeChange change = new CompositeChange();
    final Collection<Tuple<Territory, Collection<Unit>>> changeList = new ArrayList<>();
    for (final Territory currTerritory : territories) {
        final TerritoryAttachment ta = TerritoryAttachment.get(currTerritory);
        // if ownership should change in this territory
        if (ta != null && ta.getChangeUnitOwners() != null && !ta.getChangeUnitOwners().isEmpty()) {
            final Collection<PlayerID> terrNewOwners = ta.getChangeUnitOwners();
            for (final PlayerID terrNewOwner : terrNewOwners) {
                if (possibleNewOwners.contains(terrNewOwner)) {
                    // PlayerOwnerChange
                    final Collection<Unit> units = currTerritory.getUnits().getMatches(Matches.unitOwnedBy(player).and(Matches.unitCanBeGivenByTerritoryTo(terrNewOwner)));
                    if (!units.isEmpty()) {
                        change.add(ChangeFactory.changeOwner(units, terrNewOwner, currTerritory));
                        changeList.add(Tuple.of(currTerritory, units));
                    }
                }
            }
        }
    }
    if (!change.isEmpty() && !changeList.isEmpty()) {
        if (changeList.size() == 1) {
            final Tuple<Territory, Collection<Unit>> tuple = changeList.iterator().next();
            bridge.getHistoryWriter().startEvent("Some Units in " + tuple.getFirst().getName() + " change ownership: " + MyFormatter.unitsToTextNoOwner(tuple.getSecond()), tuple.getSecond());
        } else {
            bridge.getHistoryWriter().startEvent("Units Change Ownership");
            for (final Tuple<Territory, Collection<Unit>> tuple : changeList) {
                bridge.getHistoryWriter().addChildToEvent("Some Units in " + tuple.getFirst().getName() + " change ownership: " + MyFormatter.unitsToTextNoOwner(tuple.getSecond()), tuple.getSecond());
            }
        }
        bridge.addChange(change);
    }
}
Also used : PlayerID(games.strategy.engine.data.PlayerID) Territory(games.strategy.engine.data.Territory) TerritoryAttachment(games.strategy.triplea.attachments.TerritoryAttachment) ArrayList(java.util.ArrayList) Unit(games.strategy.engine.data.Unit) PlayerAttachment(games.strategy.triplea.attachments.PlayerAttachment) Collection(java.util.Collection) CompositeChange(games.strategy.engine.data.CompositeChange) Tuple(games.strategy.util.Tuple)

Example 24 with TerritoryAttachment

use of games.strategy.triplea.attachments.TerritoryAttachment in project triplea by triplea-game.

the class WW2V3Year41Test method testFactoryPlace.

@Test
public void testFactoryPlace() {
    // Set up game
    final PlayerID british = GameDataTestUtil.british(gameData);
    final ITestDelegateBridge delegateBridge = getDelegateBridge(british(gameData));
    // Set up the territories
    final Territory egypt = territory("Union of South Africa", gameData);
    // Set up the unit types
    final UnitType factoryType = GameDataTestUtil.factory(gameData);
    // Set up the move delegate
    final PlaceDelegate placeDelegate = placeDelegate(gameData);
    delegateBridge.setStepName("Place");
    delegateBridge.setPlayerId(british);
    placeDelegate.setDelegateBridgeAndPlayer(delegateBridge);
    placeDelegate.start();
    // Add the factory
    final IntegerMap<UnitType> map = new IntegerMap<>();
    map.add(factoryType, 1);
    addTo(british(gameData), factory(gameData).create(1, british(gameData)), gameData);
    // Place the factory
    final String response = placeDelegate.placeUnits(GameDataTestUtil.getUnits(map, british), egypt);
    assertValid(response);
    // placeUnits performPlace
    // get production and unit production values
    final TerritoryAttachment ta = TerritoryAttachment.get(egypt);
    assertEquals(ta.getUnitProduction(), ta.getProduction());
}
Also used : IntegerMap(games.strategy.util.IntegerMap) PlayerID(games.strategy.engine.data.PlayerID) Territory(games.strategy.engine.data.Territory) UnitType(games.strategy.engine.data.UnitType) TerritoryAttachment(games.strategy.triplea.attachments.TerritoryAttachment) ITestDelegateBridge(games.strategy.engine.data.ITestDelegateBridge) GameDataTestUtil.bidPlaceDelegate(games.strategy.triplea.delegate.GameDataTestUtil.bidPlaceDelegate) IAbstractPlaceDelegate(games.strategy.triplea.delegate.remote.IAbstractPlaceDelegate) Test(org.junit.jupiter.api.Test)

Example 25 with TerritoryAttachment

use of games.strategy.triplea.attachments.TerritoryAttachment in project triplea by triplea-game.

the class ProCombatMoveAi method determineUnitsToAttackWith.

private void determineUnitsToAttackWith(final List<ProTerritory> prioritizedTerritories, final List<Unit> alreadyMovedUnits) {
    ProLogger.info("Determine units to attack each territory with");
    final Map<Territory, ProTerritory> attackMap = territoryManager.getAttackOptions().getTerritoryMap();
    final ProOtherMoveOptions enemyAttackOptions = territoryManager.getEnemyAttackOptions();
    final Map<Unit, Set<Territory>> unitAttackMap = territoryManager.getAttackOptions().getUnitMoveMap();
    // Assign units to territories by prioritization
    while (true) {
        Map<Unit, Set<Territory>> sortedUnitAttackOptions = tryToAttackTerritories(prioritizedTerritories, alreadyMovedUnits);
        // Clear bombers
        for (final ProTerritory t : attackMap.values()) {
            t.getBombers().clear();
        }
        // Get all units that have already moved
        final Set<Unit> alreadyAttackedWithUnits = new HashSet<>();
        for (final ProTerritory t : attackMap.values()) {
            alreadyAttackedWithUnits.addAll(t.getUnits());
            alreadyAttackedWithUnits.addAll(t.getAmphibAttackMap().keySet());
        }
        // Check to see if any territories can be bombed
        final Map<Unit, Set<Territory>> bomberMoveMap = territoryManager.getAttackOptions().getBomberMoveMap();
        for (final Unit unit : bomberMoveMap.keySet()) {
            if (alreadyAttackedWithUnits.contains(unit)) {
                continue;
            }
            Optional<Territory> maxBombingTerritory = Optional.empty();
            int maxBombingScore = MIN_BOMBING_SCORE;
            for (final Territory t : bomberMoveMap.get(unit)) {
                final boolean territoryCanBeBombed = t.getUnits().anyMatch(Matches.unitCanProduceUnitsAndCanBeDamaged());
                if (territoryCanBeBombed && canAirSafelyLandAfterAttack(unit, t)) {
                    final int noAaBombingDefense = t.getUnits().anyMatch(Matches.unitIsAaForBombingThisUnitOnly()) ? 0 : 1;
                    int maxDamage = 0;
                    final TerritoryAttachment ta = TerritoryAttachment.get(t);
                    if (ta != null) {
                        maxDamage = ta.getProduction();
                    }
                    final int numExistingBombers = attackMap.get(t).getBombers().size();
                    final int remainingDamagePotential = maxDamage - 3 * numExistingBombers;
                    final int bombingScore = (1 + 9 * noAaBombingDefense) * remainingDamagePotential;
                    if (bombingScore >= maxBombingScore) {
                        maxBombingScore = bombingScore;
                        maxBombingTerritory = Optional.of(t);
                    }
                }
            }
            if (maxBombingTerritory.isPresent()) {
                final Territory t = maxBombingTerritory.get();
                attackMap.get(t).getBombers().add(unit);
                sortedUnitAttackOptions.remove(unit);
                ProLogger.debug("Add bomber (" + unit + ") to " + t);
            }
        }
        // Re-sort attack options
        sortedUnitAttackOptions = ProSortMoveOptionsUtils.sortUnitNeededOptionsThenAttack(player, sortedUnitAttackOptions, attackMap, ProData.unitTerritoryMap, calc);
        // Set air units in any territory with no AA (don't move planes to empty territories)
        for (final Iterator<Unit> it = sortedUnitAttackOptions.keySet().iterator(); it.hasNext(); ) {
            final Unit unit = it.next();
            final boolean isAirUnit = UnitAttachment.get(unit.getType()).getIsAir();
            if (!isAirUnit) {
                // skip non-air units
                continue;
            }
            Territory minWinTerritory = null;
            double minWinPercentage = Double.MAX_VALUE;
            for (final Territory t : sortedUnitAttackOptions.get(unit)) {
                final ProTerritory patd = attackMap.get(t);
                // Check if air unit should avoid this territory due to no guaranteed safe landing location
                final boolean isEnemyFactory = ProMatches.territoryHasInfraFactoryAndIsEnemyLand(player, data).test(t);
                if (!isEnemyFactory && !canAirSafelyLandAfterAttack(unit, t)) {
                    continue;
                }
                if (patd.getBattleResult() == null) {
                    patd.setBattleResult(calc.estimateAttackBattleResults(t, patd.getUnits(), patd.getMaxEnemyDefenders(player, data), patd.getBombardTerritoryMap().keySet()));
                }
                final ProBattleResult result = patd.getBattleResult();
                if (result.getWinPercentage() < minWinPercentage || (!result.isHasLandUnitRemaining() && minWinTerritory == null)) {
                    final List<Unit> attackingUnits = patd.getUnits();
                    final List<Unit> defendingUnits = patd.getMaxEnemyDefenders(player, data);
                    final boolean isOverwhelmingWin = ProBattleUtils.checkForOverwhelmingWin(t, attackingUnits, defendingUnits);
                    final boolean hasAa = defendingUnits.stream().anyMatch(Matches.unitIsAaForAnything());
                    if (!hasAa && !isOverwhelmingWin) {
                        minWinPercentage = result.getWinPercentage();
                        minWinTerritory = t;
                    }
                }
            }
            if (minWinTerritory != null) {
                attackMap.get(minWinTerritory).addUnit(unit);
                attackMap.get(minWinTerritory).setBattleResult(null);
                it.remove();
            }
        }
        // Re-sort attack options
        sortedUnitAttackOptions = ProSortMoveOptionsUtils.sortUnitNeededOptionsThenAttack(player, sortedUnitAttackOptions, attackMap, ProData.unitTerritoryMap, calc);
        // Find territory that we can try to hold that needs unit
        for (final Iterator<Unit> it = sortedUnitAttackOptions.keySet().iterator(); it.hasNext(); ) {
            final Unit unit = it.next();
            Territory minWinTerritory = null;
            for (final Territory t : sortedUnitAttackOptions.get(unit)) {
                final ProTerritory patd = attackMap.get(t);
                if (patd.isCanHold()) {
                    // Check if I already have enough attack units to win in 2 rounds
                    if (patd.getBattleResult() == null) {
                        patd.setBattleResult(calc.estimateAttackBattleResults(t, patd.getUnits(), patd.getMaxEnemyDefenders(player, data), patd.getBombardTerritoryMap().keySet()));
                    }
                    final ProBattleResult result = patd.getBattleResult();
                    final List<Unit> attackingUnits = patd.getUnits();
                    final List<Unit> defendingUnits = patd.getMaxEnemyDefenders(player, data);
                    final boolean isOverwhelmingWin = ProBattleUtils.checkForOverwhelmingWin(t, attackingUnits, defendingUnits);
                    if (!isOverwhelmingWin && result.getBattleRounds() > 2) {
                        minWinTerritory = t;
                        break;
                    }
                }
            }
            if (minWinTerritory != null) {
                attackMap.get(minWinTerritory).addUnit(unit);
                attackMap.get(minWinTerritory).setBattleResult(null);
                it.remove();
            }
        }
        // Re-sort attack options
        sortedUnitAttackOptions = ProSortMoveOptionsUtils.sortUnitNeededOptionsThenAttack(player, sortedUnitAttackOptions, attackMap, ProData.unitTerritoryMap, calc);
        // Add sea units to any territory that significantly increases TUV gain
        for (final Iterator<Unit> it = sortedUnitAttackOptions.keySet().iterator(); it.hasNext(); ) {
            final Unit unit = it.next();
            final boolean isSeaUnit = UnitAttachment.get(unit.getType()).getIsSea();
            if (!isSeaUnit) {
                // skip non-sea units
                continue;
            }
            for (final Territory t : sortedUnitAttackOptions.get(unit)) {
                final ProTerritory patd = attackMap.get(t);
                if (attackMap.get(t).getBattleResult() == null) {
                    attackMap.get(t).setBattleResult(calc.estimateAttackBattleResults(t, patd.getUnits(), patd.getMaxEnemyDefenders(player, data), patd.getBombardTerritoryMap().keySet()));
                }
                final ProBattleResult result = attackMap.get(t).getBattleResult();
                final List<Unit> attackers = new ArrayList<>(patd.getUnits());
                attackers.add(unit);
                final ProBattleResult result2 = calc.estimateAttackBattleResults(t, attackers, patd.getMaxEnemyDefenders(player, data), patd.getBombardTerritoryMap().keySet());
                final double unitValue = ProData.unitValueMap.getInt(unit.getType());
                if ((result2.getTuvSwing() - unitValue / 3) > result.getTuvSwing()) {
                    attackMap.get(t).addUnit(unit);
                    attackMap.get(t).setBattleResult(null);
                    it.remove();
                    break;
                }
            }
        }
        // Determine if all attacks are worth it
        final List<Unit> usedUnits = new ArrayList<>();
        for (final ProTerritory patd : prioritizedTerritories) {
            usedUnits.addAll(patd.getUnits());
        }
        ProTerritory territoryToRemove = null;
        for (final ProTerritory patd : prioritizedTerritories) {
            final Territory t = patd.getTerritory();
            // Find battle result
            if (patd.getBattleResult() == null) {
                patd.setBattleResult(calc.estimateAttackBattleResults(t, patd.getUnits(), patd.getMaxEnemyDefenders(player, data), patd.getBombardTerritoryMap().keySet()));
            }
            final ProBattleResult result = patd.getBattleResult();
            // Determine enemy counter attack results
            boolean canHold = true;
            double enemyCounterTuvSwing = 0;
            if (enemyAttackOptions.getMax(t) != null && !ProMatches.territoryIsWaterAndAdjacentToOwnedFactory(player, data).test(t)) {
                List<Unit> remainingUnitsToDefendWith = CollectionUtils.getMatches(result.getAverageAttackersRemaining(), Matches.unitIsAir().negate());
                ProBattleResult result2 = calc.calculateBattleResults(t, patd.getMaxEnemyUnits(), remainingUnitsToDefendWith, patd.getMaxBombardUnits());
                if (patd.isCanHold() && result2.getTuvSwing() > 0) {
                    final List<Unit> unusedUnits = new ArrayList<>(patd.getMaxUnits());
                    unusedUnits.addAll(patd.getMaxAmphibUnits());
                    unusedUnits.removeAll(usedUnits);
                    unusedUnits.addAll(remainingUnitsToDefendWith);
                    final ProBattleResult result3 = calc.calculateBattleResults(t, patd.getMaxEnemyUnits(), unusedUnits, patd.getMaxBombardUnits());
                    if (result3.getTuvSwing() < result2.getTuvSwing()) {
                        result2 = result3;
                        remainingUnitsToDefendWith = unusedUnits;
                    }
                }
                canHold = (!result2.isHasLandUnitRemaining() && !t.isWater()) || (result2.getTuvSwing() < 0) || (result2.getWinPercentage() < ProData.minWinPercentage);
                if (result2.getTuvSwing() > 0) {
                    enemyCounterTuvSwing = result2.getTuvSwing();
                }
                ProLogger.trace("Territory=" + t.getName() + ", CanHold=" + canHold + ", MyDefenders=" + remainingUnitsToDefendWith.size() + ", EnemyAttackers=" + patd.getMaxEnemyUnits().size() + ", win%=" + result2.getWinPercentage() + ", EnemyTUVSwing=" + result2.getTuvSwing() + ", hasLandUnitRemaining=" + result2.isHasLandUnitRemaining());
            }
            // Find attack value
            final boolean isNeutral = (!t.isWater() && t.getOwner().isNull());
            final int isLand = !t.isWater() ? 1 : 0;
            final int isCanHold = canHold ? 1 : 0;
            final int isCantHoldAmphib = !canHold && !patd.getAmphibAttackMap().isEmpty() ? 1 : 0;
            final int isFactory = ProMatches.territoryHasInfraFactoryAndIsLand().test(t) ? 1 : 0;
            final int isFfa = ProUtils.isFfa(data, player) ? 1 : 0;
            final int production = TerritoryAttachment.getProduction(t);
            double capitalValue = 0;
            final TerritoryAttachment ta = TerritoryAttachment.get(t);
            if (ta != null && ta.isCapital()) {
                capitalValue = ProUtils.getPlayerProduction(t.getOwner(), data);
            }
            final double territoryValue = (1 + isLand - isCantHoldAmphib + isFactory + isCanHold * (1 + 2 * isFfa + 2 * isFactory)) * production + capitalValue;
            double tuvSwing = result.getTuvSwing();
            if (isFfa == 1 && tuvSwing > 0) {
                tuvSwing *= 0.5;
            }
            final double attackValue = tuvSwing + territoryValue * result.getWinPercentage() / 100 - enemyCounterTuvSwing * 2 / 3;
            boolean allUnitsCanAttackOtherTerritory = true;
            if (isNeutral && attackValue < 0) {
                for (final Unit u : patd.getUnits()) {
                    boolean canAttackOtherTerritory = false;
                    for (final ProTerritory patd2 : prioritizedTerritories) {
                        if (!patd.equals(patd2) && unitAttackMap.get(u) != null && unitAttackMap.get(u).contains(patd2.getTerritory())) {
                            canAttackOtherTerritory = true;
                            break;
                        }
                    }
                    if (!canAttackOtherTerritory) {
                        allUnitsCanAttackOtherTerritory = false;
                        break;
                    }
                }
            }
            // Determine whether to remove attack
            if (!patd.isStrafing() && (result.getWinPercentage() < ProData.minWinPercentage || !result.isHasLandUnitRemaining() || (isNeutral && !canHold) || (attackValue < 0 && (!isNeutral || allUnitsCanAttackOtherTerritory || result.getBattleRounds() >= 4)))) {
                territoryToRemove = patd;
            }
            ProLogger.debug(patd.getResultString() + ", attackValue=" + attackValue + ", territoryValue=" + territoryValue + ", allUnitsCanAttackOtherTerritory=" + allUnitsCanAttackOtherTerritory + " with attackers=" + patd.getUnits());
        }
        // Determine whether all attacks are successful or try to hold fewer territories
        if (territoryToRemove == null) {
            break;
        }
        prioritizedTerritories.remove(territoryToRemove);
        ProLogger.debug("Removing " + territoryToRemove.getTerritory().getName());
    }
}
Also used : Territory(games.strategy.engine.data.Territory) ProTerritory(games.strategy.triplea.ai.pro.data.ProTerritory) HashSet(java.util.HashSet) Set(java.util.Set) ProTerritory(games.strategy.triplea.ai.pro.data.ProTerritory) TerritoryAttachment(games.strategy.triplea.attachments.TerritoryAttachment) 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

TerritoryAttachment (games.strategy.triplea.attachments.TerritoryAttachment)36 Territory (games.strategy.engine.data.Territory)29 Unit (games.strategy.engine.data.Unit)24 TripleAUnit (games.strategy.triplea.TripleAUnit)19 ArrayList (java.util.ArrayList)14 PlayerID (games.strategy.engine.data.PlayerID)13 GameData (games.strategy.engine.data.GameData)9 HashSet (java.util.HashSet)8 UnitAttachment (games.strategy.triplea.attachments.UnitAttachment)7 ProTerritory (games.strategy.triplea.ai.pro.data.ProTerritory)6 UnitType (games.strategy.engine.data.UnitType)5 ProBattleResult (games.strategy.triplea.ai.pro.data.ProBattleResult)5 CompositeChange (games.strategy.engine.data.CompositeChange)4 Resource (games.strategy.engine.data.Resource)4 ProOtherMoveOptions (games.strategy.triplea.ai.pro.data.ProOtherMoveOptions)4 PlayerAttachment (games.strategy.triplea.attachments.PlayerAttachment)4 IntegerMap (games.strategy.util.IntegerMap)4 RelationshipTracker (games.strategy.engine.data.RelationshipTracker)3 ProPlaceTerritory (games.strategy.triplea.ai.pro.data.ProPlaceTerritory)3 ProPurchaseTerritory (games.strategy.triplea.ai.pro.data.ProPurchaseTerritory)3