Search in sources :

Example 6 with ProPlaceTerritory

use of games.strategy.triplea.ai.pro.data.ProPlaceTerritory in project triplea by triplea-game.

the class ProPurchaseAi method purchaseLandUnits.

private void purchaseLandUnits(final Map<Territory, ProPurchaseTerritory> purchaseTerritories, final List<ProPlaceTerritory> prioritizedLandTerritories, final ProPurchaseOptionMap purchaseOptions, final Map<Territory, Double> territoryValueMap) {
    final List<Unit> unplacedUnits = player.getUnits().getMatches(Matches.unitIsNotSea());
    if (resourceTracker.isEmpty() && unplacedUnits.isEmpty()) {
        return;
    }
    ProLogger.info("Purchase land units with resources: " + resourceTracker);
    if (!unplacedUnits.isEmpty()) {
        ProLogger.info("Purchase land units with unplaced units=" + unplacedUnits);
    }
    // Loop through prioritized territories and purchase land units
    for (final ProPlaceTerritory placeTerritory : prioritizedLandTerritories) {
        final Territory t = placeTerritory.getTerritory();
        ProLogger.debug("Checking land place for " + t.getName());
        // Check remaining production
        int remainingUnitProduction = purchaseTerritories.get(t).getRemainingUnitProduction();
        ProLogger.debug(t + ", remainingUnitProduction=" + remainingUnitProduction);
        if (remainingUnitProduction <= 0) {
            continue;
        }
        // Determine most cost efficient units that can be produced in this territory
        final List<ProPurchaseOption> landFodderOptions = ProPurchaseUtils.findPurchaseOptionsForTerritory(player, purchaseOptions.getLandFodderOptions(), t, isBid);
        final List<ProPurchaseOption> landAttackOptions = ProPurchaseUtils.findPurchaseOptionsForTerritory(player, purchaseOptions.getLandAttackOptions(), t, isBid);
        final List<ProPurchaseOption> landDefenseOptions = ProPurchaseUtils.findPurchaseOptionsForTerritory(player, purchaseOptions.getLandDefenseOptions(), t, isBid);
        // Determine enemy distance and locally owned units
        int enemyDistance = ProUtils.getClosestEnemyOrNeutralLandTerritoryDistance(data, player, t, territoryValueMap);
        if (enemyDistance <= 0) {
            enemyDistance = 10;
        }
        final int fodderPercent = 80 - enemyDistance * 5;
        ProLogger.debug(t + ", enemyDistance=" + enemyDistance + ", fodderPercent=" + fodderPercent);
        final Set<Territory> neighbors = data.getMap().getNeighbors(t, 2, ProMatches.territoryCanMoveLandUnits(player, data, false));
        neighbors.add(t);
        final List<Unit> ownedLocalUnits = new ArrayList<>();
        for (final Territory neighbor : neighbors) {
            ownedLocalUnits.addAll(neighbor.getUnits().getMatches(Matches.unitIsOwnedBy(player)));
        }
        // Check for unplaced units
        final List<Unit> unitsToPlace = new ArrayList<>();
        for (final Iterator<Unit> it = unplacedUnits.iterator(); it.hasNext(); ) {
            final Unit u = it.next();
            if (remainingUnitProduction > 0 && ProPurchaseUtils.canUnitsBePlaced(Collections.singletonList(u), player, t, isBid)) {
                remainingUnitProduction--;
                unitsToPlace.add(u);
                it.remove();
                ProLogger.trace("Selected unplaced unit=" + u);
            }
        }
        // Purchase as many units as possible
        int addedFodderUnits = 0;
        double attackAndDefenseDifference = 0;
        boolean selectFodderUnit = true;
        while (true) {
            // Remove options that cost too much PUs or production
            ProPurchaseUtils.removeInvalidPurchaseOptions(player, startOfTurnData, landFodderOptions, resourceTracker, remainingUnitProduction, unitsToPlace, purchaseTerritories);
            ProPurchaseUtils.removeInvalidPurchaseOptions(player, startOfTurnData, landAttackOptions, resourceTracker, remainingUnitProduction, unitsToPlace, purchaseTerritories);
            ProPurchaseUtils.removeInvalidPurchaseOptions(player, startOfTurnData, landDefenseOptions, resourceTracker, remainingUnitProduction, unitsToPlace, purchaseTerritories);
            // Select purchase option
            Optional<ProPurchaseOption> optionalSelectedOption = Optional.empty();
            if (!selectFodderUnit && attackAndDefenseDifference > 0 && !landDefenseOptions.isEmpty()) {
                final Map<ProPurchaseOption, Double> defenseEfficiencies = new HashMap<>();
                for (final ProPurchaseOption ppo : landDefenseOptions) {
                    defenseEfficiencies.put(ppo, ppo.getDefenseEfficiency2(enemyDistance, data, ownedLocalUnits, unitsToPlace));
                }
                optionalSelectedOption = ProPurchaseUtils.randomizePurchaseOption(defenseEfficiencies, "Land Defense");
            } else if (!selectFodderUnit && !landAttackOptions.isEmpty()) {
                final Map<ProPurchaseOption, Double> attackEfficiencies = new HashMap<>();
                for (final ProPurchaseOption ppo : landAttackOptions) {
                    attackEfficiencies.put(ppo, ppo.getAttackEfficiency2(enemyDistance, data, ownedLocalUnits, unitsToPlace));
                }
                optionalSelectedOption = ProPurchaseUtils.randomizePurchaseOption(attackEfficiencies, "Land Attack");
            } else if (!landFodderOptions.isEmpty()) {
                final Map<ProPurchaseOption, Double> fodderEfficiencies = new HashMap<>();
                for (final ProPurchaseOption ppo : landFodderOptions) {
                    fodderEfficiencies.put(ppo, ppo.getFodderEfficiency(enemyDistance, data, ownedLocalUnits, unitsToPlace));
                }
                optionalSelectedOption = ProPurchaseUtils.randomizePurchaseOption(fodderEfficiencies, "Land Fodder");
                if (optionalSelectedOption.isPresent()) {
                    addedFodderUnits += optionalSelectedOption.get().getQuantity();
                }
            }
            if (!optionalSelectedOption.isPresent()) {
                break;
            }
            final ProPurchaseOption selectedOption = optionalSelectedOption.get();
            // Create new temp units
            resourceTracker.purchase(selectedOption);
            remainingUnitProduction -= selectedOption.getQuantity();
            unitsToPlace.addAll(selectedOption.getUnitType().create(selectedOption.getQuantity(), player, true));
            attackAndDefenseDifference += (selectedOption.getAttack() - selectedOption.getDefense());
            selectFodderUnit = ((double) addedFodderUnits / unitsToPlace.size() * 100) <= fodderPercent;
            ProLogger.trace("Selected unit=" + selectedOption.getUnitType().getName());
        }
        // Add units to place territory
        placeTerritory.getPlaceUnits().addAll(unitsToPlace);
        ProLogger.debug(t + ", placedUnits=" + unitsToPlace);
    }
}
Also used : ProPlaceTerritory(games.strategy.triplea.ai.pro.data.ProPlaceTerritory) ProPurchaseTerritory(games.strategy.triplea.ai.pro.data.ProPurchaseTerritory) Territory(games.strategy.engine.data.Territory) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) TripleAUnit(games.strategy.triplea.TripleAUnit) Unit(games.strategy.engine.data.Unit) ProPlaceTerritory(games.strategy.triplea.ai.pro.data.ProPlaceTerritory) ProPurchaseOption(games.strategy.triplea.ai.pro.data.ProPurchaseOption) HashMap(java.util.HashMap) Map(java.util.Map) IntegerMap(games.strategy.util.IntegerMap) ProPurchaseOptionMap(games.strategy.triplea.ai.pro.data.ProPurchaseOptionMap)

Example 7 with ProPlaceTerritory

use of games.strategy.triplea.ai.pro.data.ProPlaceTerritory in project triplea by triplea-game.

the class ProNonCombatMoveAi method findUnitsThatCantMove.

private void findUnitsThatCantMove(final Map<Territory, ProPurchaseTerritory> purchaseTerritories, final List<ProPurchaseOption> landPurchaseOptions) {
    ProLogger.info("Find units that can't move");
    final Map<Territory, ProTerritory> moveMap = territoryManager.getDefendOptions().getTerritoryMap();
    final Map<Unit, Set<Territory>> unitMoveMap = territoryManager.getDefendOptions().getUnitMoveMap();
    final List<ProTransport> transportMapList = territoryManager.getDefendOptions().getTransportList();
    // Add all units that can't move (allied units, 0 move units, etc)
    for (final Territory t : moveMap.keySet()) {
        moveMap.get(t).getCantMoveUnits().addAll(t.getUnits().getMatches(ProMatches.unitCantBeMovedAndIsAlliedDefender(player, data, t)));
    }
    // Add all units that only have 1 move option and can't be transported
    for (final Iterator<Unit> it = unitMoveMap.keySet().iterator(); it.hasNext(); ) {
        final Unit u = it.next();
        if (unitMoveMap.get(u).size() == 1) {
            final Territory onlyTerritory = unitMoveMap.get(u).iterator().next();
            if (onlyTerritory.equals(unitTerritoryMap.get(u))) {
                boolean canBeTransported = false;
                for (final ProTransport pad : transportMapList) {
                    for (final Territory t : pad.getTransportMap().keySet()) {
                        if (pad.getTransportMap().get(t).contains(onlyTerritory)) {
                            canBeTransported = true;
                        }
                    }
                    for (final Territory t : pad.getSeaTransportMap().keySet()) {
                        if (pad.getSeaTransportMap().get(t).contains(onlyTerritory)) {
                            canBeTransported = true;
                        }
                    }
                }
                if (!canBeTransported) {
                    moveMap.get(onlyTerritory).getCantMoveUnits().add(u);
                    it.remove();
                }
            }
        }
    }
    // Check if purchase units are known yet
    if (purchaseTerritories != null) {
        // Add all units that will be purchased
        for (final ProPurchaseTerritory ppt : purchaseTerritories.values()) {
            for (final ProPlaceTerritory placeTerritory : ppt.getCanPlaceTerritories()) {
                final Territory t = placeTerritory.getTerritory();
                if (moveMap.get(t) != null) {
                    moveMap.get(t).getCantMoveUnits().addAll(placeTerritory.getPlaceUnits());
                }
            }
        }
    } else {
        // Add max defenders that can be purchased to each territory
        for (final Territory t : moveMap.keySet()) {
            if (ProMatches.territoryHasNonMobileInfraFactoryAndIsNotConqueredOwnedLand(player, data).test(t)) {
                moveMap.get(t).getCantMoveUnits().addAll(ProPurchaseUtils.findMaxPurchaseDefenders(player, t, landPurchaseOptions));
            }
        }
    }
    // Log can't move units per territory
    for (final Territory t : moveMap.keySet()) {
        if (!moveMap.get(t).getCantMoveUnits().isEmpty()) {
            ProLogger.trace(t + " has units that can't move: " + moveMap.get(t).getCantMoveUnits());
        }
    }
}
Also used : ProPlaceTerritory(games.strategy.triplea.ai.pro.data.ProPlaceTerritory) ProPurchaseTerritory(games.strategy.triplea.ai.pro.data.ProPurchaseTerritory) ProTerritory(games.strategy.triplea.ai.pro.data.ProTerritory) Territory(games.strategy.engine.data.Territory) Set(java.util.Set) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet) ProTransport(games.strategy.triplea.ai.pro.data.ProTransport) ProPlaceTerritory(games.strategy.triplea.ai.pro.data.ProPlaceTerritory) ProTerritory(games.strategy.triplea.ai.pro.data.ProTerritory) ProPurchaseTerritory(games.strategy.triplea.ai.pro.data.ProPurchaseTerritory) TripleAUnit(games.strategy.triplea.TripleAUnit) Unit(games.strategy.engine.data.Unit)

Example 8 with ProPlaceTerritory

use of games.strategy.triplea.ai.pro.data.ProPlaceTerritory in project triplea by triplea-game.

the class ProBattleUtils method territoryHasLocalLandSuperiority.

public static boolean territoryHasLocalLandSuperiority(final Territory t, final int distance, final PlayerID player, final Map<Territory, ProPurchaseTerritory> purchaseTerritories) {
    final GameData data = ProData.getData();
    if (t == null) {
        return true;
    }
    for (int i = 2; i <= distance; i++) {
        // Find enemy strength
        final Set<Territory> nearbyTerritoriesForEnemy = data.getMap().getNeighbors(t, i, ProMatches.territoryCanMoveLandUnits(player, data, false));
        nearbyTerritoriesForEnemy.add(t);
        final List<Unit> enemyUnits = new ArrayList<>();
        for (final Territory nearbyTerritory : nearbyTerritoriesForEnemy) {
            enemyUnits.addAll(nearbyTerritory.getUnits().getMatches(ProMatches.unitIsEnemyNotNeutral(player, data)));
        }
        // Find allied strength
        final Set<Territory> nearbyTerritoriesForAllied = data.getMap().getNeighbors(t, i - 1, ProMatches.territoryCanMoveLandUnits(player, data, false));
        nearbyTerritoriesForAllied.add(t);
        final List<Unit> alliedUnits = new ArrayList<>();
        for (final Territory nearbyTerritory : nearbyTerritoriesForAllied) {
            alliedUnits.addAll(nearbyTerritory.getUnits().getMatches(Matches.isUnitAllied(player, data)));
        }
        for (final ProPurchaseTerritory purchaseTerritory : purchaseTerritories.values()) {
            for (final ProPlaceTerritory ppt : purchaseTerritory.getCanPlaceTerritories()) {
                if (nearbyTerritoriesForAllied.contains(ppt.getTerritory())) {
                    alliedUnits.addAll(ppt.getPlaceUnits());
                }
            }
        }
        // Determine strength difference
        final double strengthDifference = estimateStrengthDifference(t, enemyUnits, alliedUnits);
        ProLogger.trace(t + ", current enemy land strengthDifference=" + strengthDifference + ", distance=" + i + ", enemySize=" + enemyUnits.size() + ", alliedSize=" + alliedUnits.size());
        if (strengthDifference > 50) {
            return false;
        }
    }
    return true;
}
Also used : ProPlaceTerritory(games.strategy.triplea.ai.pro.data.ProPlaceTerritory) Territory(games.strategy.engine.data.Territory) ProTerritory(games.strategy.triplea.ai.pro.data.ProTerritory) ProPurchaseTerritory(games.strategy.triplea.ai.pro.data.ProPurchaseTerritory) GameData(games.strategy.engine.data.GameData) ProPlaceTerritory(games.strategy.triplea.ai.pro.data.ProPlaceTerritory) ArrayList(java.util.ArrayList) ProPurchaseTerritory(games.strategy.triplea.ai.pro.data.ProPurchaseTerritory) Unit(games.strategy.engine.data.Unit)

Example 9 with ProPlaceTerritory

use of games.strategy.triplea.ai.pro.data.ProPlaceTerritory in project triplea by triplea-game.

the class ProPurchaseUtils method removeInvalidPurchaseOptions.

public static List<ProPurchaseOption> removeInvalidPurchaseOptions(final PlayerID player, final GameData data, final List<ProPurchaseOption> purchaseOptions, final ProResourceTracker resourceTracker, final int remainingUnitProduction, final List<Unit> unitsToPlace, final Map<Territory, ProPurchaseTerritory> purchaseTerritories) {
    for (final Iterator<ProPurchaseOption> it = purchaseOptions.iterator(); it.hasNext(); ) {
        final ProPurchaseOption purchaseOption = it.next();
        // Check PU cost and production
        if (!resourceTracker.hasEnough(purchaseOption) || purchaseOption.getQuantity() > remainingUnitProduction) {
            it.remove();
            continue;
        }
        // Check max unit limits (-1 is unlimited)
        final int maxBuilt = purchaseOption.getMaxBuiltPerPlayer();
        final UnitType type = purchaseOption.getUnitType();
        if (maxBuilt == 0) {
            it.remove();
        } else if (maxBuilt > 0) {
            // Find number of unit type that are already built and about to be placed
            int currentlyBuilt = 0;
            final Predicate<Unit> unitTypeOwnedBy = Matches.unitIsOfType(type).and(Matches.unitIsOwnedBy(player));
            final List<Territory> allTerritories = data.getMap().getTerritories();
            for (final Territory t : allTerritories) {
                currentlyBuilt += t.getUnits().countMatches(unitTypeOwnedBy);
            }
            currentlyBuilt += CollectionUtils.countMatches(unitsToPlace, unitTypeOwnedBy);
            for (final ProPurchaseTerritory t : purchaseTerritories.values()) {
                for (final ProPlaceTerritory placeTerritory : t.getCanPlaceTerritories()) {
                    currentlyBuilt += CollectionUtils.countMatches(placeTerritory.getPlaceUnits(), unitTypeOwnedBy);
                }
            }
            final int allowedBuild = maxBuilt - currentlyBuilt;
            if (allowedBuild - purchaseOption.getQuantity() < 0) {
                it.remove();
            }
        }
    }
    return purchaseOptions;
}
Also used : ProPlaceTerritory(games.strategy.triplea.ai.pro.data.ProPlaceTerritory) ProPurchaseTerritory(games.strategy.triplea.ai.pro.data.ProPurchaseTerritory) Territory(games.strategy.engine.data.Territory) ProPlaceTerritory(games.strategy.triplea.ai.pro.data.ProPlaceTerritory) UnitType(games.strategy.engine.data.UnitType) ProPurchaseOption(games.strategy.triplea.ai.pro.data.ProPurchaseOption) ProPurchaseTerritory(games.strategy.triplea.ai.pro.data.ProPurchaseTerritory) ArrayList(java.util.ArrayList) List(java.util.List) Predicate(java.util.function.Predicate)

Example 10 with ProPlaceTerritory

use of games.strategy.triplea.ai.pro.data.ProPlaceTerritory in project triplea by triplea-game.

the class ProPurchaseAi method place.

void place(final Map<Territory, ProPurchaseTerritory> purchaseTerritories, final IAbstractPlaceDelegate placeDelegate) {
    ProLogger.info("Starting place phase");
    data = ProData.getData();
    player = ProData.getPlayer();
    territoryManager = new ProTerritoryManager(calc);
    if (purchaseTerritories != null) {
        // Place all units calculated during purchase phase (land then sea to reduce failed placements)
        for (final ProPurchaseTerritory t : purchaseTerritories.values()) {
            for (final ProPlaceTerritory ppt : t.getCanPlaceTerritories()) {
                if (!ppt.getTerritory().isWater()) {
                    final List<Unit> unitsToPlace = new ArrayList<>();
                    for (final Unit placeUnit : ppt.getPlaceUnits()) {
                        for (final Unit myUnit : player.getUnits()) {
                            if (myUnit.getType().equals(placeUnit.getType()) && !unitsToPlace.contains(myUnit)) {
                                unitsToPlace.add(myUnit);
                                break;
                            }
                        }
                    }
                    doPlace(data.getMap().getTerritory(ppt.getTerritory().getName()), unitsToPlace, placeDelegate);
                    ProLogger.debug(ppt.getTerritory() + " placed units: " + unitsToPlace);
                }
            }
        }
        for (final ProPurchaseTerritory t : purchaseTerritories.values()) {
            for (final ProPlaceTerritory ppt : t.getCanPlaceTerritories()) {
                if (ppt.getTerritory().isWater()) {
                    final List<Unit> unitsToPlace = new ArrayList<>();
                    for (final Unit placeUnit : ppt.getPlaceUnits()) {
                        for (final Unit myUnit : player.getUnits()) {
                            if (myUnit.getType().equals(placeUnit.getType()) && !unitsToPlace.contains(myUnit)) {
                                unitsToPlace.add(myUnit);
                                break;
                            }
                        }
                    }
                    doPlace(data.getMap().getTerritory(ppt.getTerritory().getName()), unitsToPlace, placeDelegate);
                    ProLogger.debug(ppt.getTerritory() + " placed units: " + unitsToPlace);
                }
            }
        }
    }
    // Place remaining units (currently only implemented to handle land units, ex. WW2v3 China)
    if (player.getUnits().getUnits().isEmpty()) {
        return;
    }
    // Current data at the start of place
    ProLogger.debug("Remaining units to place: " + player.getUnits().getUnits());
    // Find all place territories
    final Map<Territory, ProPurchaseTerritory> placeNonConstructionTerritories = ProPurchaseUtils.findPurchaseTerritories(player);
    // Determine max enemy attack units and current allied defenders
    findDefendersInPlaceTerritories(placeNonConstructionTerritories);
    // Prioritize land territories that need defended and place additional defenders
    final List<ProPlaceTerritory> needToDefendLandTerritories = prioritizeTerritoriesToDefend(placeNonConstructionTerritories, true);
    placeDefenders(placeNonConstructionTerritories, needToDefendLandTerritories, placeDelegate);
    // Find strategic value for each territory
    ProLogger.info("Find strategic value for place territories");
    final Map<Territory, Double> territoryValueMap = ProTerritoryValueUtils.findTerritoryValues(player, new ArrayList<>(), new ArrayList<>());
    for (final ProPurchaseTerritory t : placeNonConstructionTerritories.values()) {
        for (final ProPlaceTerritory ppt : t.getCanPlaceTerritories()) {
            ppt.setStrategicValue(territoryValueMap.get(ppt.getTerritory()));
            ProLogger.debug(ppt.getTerritory() + ", strategicValue=" + territoryValueMap.get(ppt.getTerritory()));
        }
    }
    // Prioritize land place territories, add all territories, and then place units
    final List<ProPlaceTerritory> prioritizedLandTerritories = prioritizeLandTerritories(placeNonConstructionTerritories);
    for (final ProPurchaseTerritory ppt : placeNonConstructionTerritories.values()) {
        for (final ProPlaceTerritory placeTerritory : ppt.getCanPlaceTerritories()) {
            final Territory t = placeTerritory.getTerritory();
            if (!t.isWater() && !prioritizedLandTerritories.contains(placeTerritory)) {
                prioritizedLandTerritories.add(placeTerritory);
            }
        }
    }
    // Place regular land units
    placeLandUnits(prioritizedLandTerritories, placeDelegate, false);
    // Place isConstruction land units (needs separated since placeDelegate.getPlaceableUnits doesn't handle combined)
    placeLandUnits(prioritizedLandTerritories, placeDelegate, true);
}
Also used : ProPlaceTerritory(games.strategy.triplea.ai.pro.data.ProPlaceTerritory) ProPurchaseTerritory(games.strategy.triplea.ai.pro.data.ProPurchaseTerritory) Territory(games.strategy.engine.data.Territory) ProPlaceTerritory(games.strategy.triplea.ai.pro.data.ProPlaceTerritory) ProTerritoryManager(games.strategy.triplea.ai.pro.data.ProTerritoryManager) ArrayList(java.util.ArrayList) ProPurchaseTerritory(games.strategy.triplea.ai.pro.data.ProPurchaseTerritory) TripleAUnit(games.strategy.triplea.TripleAUnit) Unit(games.strategy.engine.data.Unit)

Aggregations

ProPlaceTerritory (games.strategy.triplea.ai.pro.data.ProPlaceTerritory)21 ProPurchaseTerritory (games.strategy.triplea.ai.pro.data.ProPurchaseTerritory)21 Territory (games.strategy.engine.data.Territory)20 Unit (games.strategy.engine.data.Unit)18 TripleAUnit (games.strategy.triplea.TripleAUnit)17 ArrayList (java.util.ArrayList)16 ProPurchaseOption (games.strategy.triplea.ai.pro.data.ProPurchaseOption)10 HashSet (java.util.HashSet)10 ProOtherMoveOptions (games.strategy.triplea.ai.pro.data.ProOtherMoveOptions)9 ProBattleResult (games.strategy.triplea.ai.pro.data.ProBattleResult)7 HashMap (java.util.HashMap)7 ProPurchaseOptionMap (games.strategy.triplea.ai.pro.data.ProPurchaseOptionMap)4 ProTerritoryManager (games.strategy.triplea.ai.pro.data.ProTerritoryManager)4 PlaceableUnits (games.strategy.triplea.delegate.dataObjects.PlaceableUnits)4 GameData (games.strategy.engine.data.GameData)3 ProductionRule (games.strategy.engine.data.ProductionRule)3 Route (games.strategy.engine.data.Route)3 ProResourceTracker (games.strategy.triplea.ai.pro.data.ProResourceTracker)3 TerritoryAttachment (games.strategy.triplea.attachments.TerritoryAttachment)3 PlayerID (games.strategy.engine.data.PlayerID)2