Search in sources :

Example 16 with Route

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

the class ProTechAi method determineEnemyBlitzStrength.

/**
 * Determine the enemy potential for blitzing a territory - all enemies are combined.
 *
 * @param blitzHere
 *        - Territory expecting to be blitzed
 * @return actual strength of enemy units (armor)
 */
private static float determineEnemyBlitzStrength(final Territory blitzHere, final List<Route> blitzTerrRoutes, final GameData data, final PlayerID enemyPlayer) {
    final HashSet<Integer> ignore = new HashSet<>();
    ignore.add(1);
    final Predicate<Unit> blitzUnit = Matches.unitIsOwnedBy(enemyPlayer).and(Matches.unitCanBlitz()).and(Matches.unitCanMove());
    final Predicate<Territory> validBlitzRoute = Matches.territoryHasNoEnemyUnits(enemyPlayer, data).and(Matches.territoryIsNotImpassableToLandUnits(enemyPlayer, data));
    final List<Route> routes = new ArrayList<>();
    final List<Unit> blitzUnits = findAttackers(blitzHere, 2, ignore, enemyPlayer, data, blitzUnit, validBlitzRoute, routes, false);
    for (final Route r : routes) {
        if (r.numberOfSteps() == 2) {
            blitzTerrRoutes.add(r);
        }
    }
    return strength(blitzUnits, true, false, true);
}
Also used : Territory(games.strategy.engine.data.Territory) ArrayList(java.util.ArrayList) Unit(games.strategy.engine.data.Unit) Route(games.strategy.engine.data.Route) HashSet(java.util.HashSet)

Example 17 with Route

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

the class ProTechAi method getStrengthOfPotentialAttackers.

/**
 * Returns the strength of all attackers to a territory.
 * Differentiates between sea and land attack
 * Determines all transports within range of territory
 * Determines all air units within range of territory (using 2 for fighters and 3 for bombers)
 * Does not check for extended range fighters or bombers
 */
private static float getStrengthOfPotentialAttackers(final Territory location, final GameData data, final PlayerID player) {
    final boolean transportsFirst = false;
    PlayerID enemyPlayer = null;
    final List<PlayerID> enemyPlayers = getEnemyPlayers(data, player);
    final HashMap<PlayerID, Float> enemyPlayerAttackMap = new HashMap<>();
    final Iterator<PlayerID> playerIter = enemyPlayers.iterator();
    if (location == null) {
        return -1000.0F;
    }
    boolean nonTransportsInAttack = false;
    final boolean onWater = location.isWater();
    if (!onWater) {
        nonTransportsInAttack = true;
    }
    final Set<Territory> waterTerr = data.getMap().getNeighbors(location, Matches.territoryIsWater());
    while (playerIter.hasNext()) {
        float seaStrength = 0.0F;
        float firstStrength = 0.0F;
        float secondStrength = 0.0F;
        float blitzStrength = 0.0F;
        float strength;
        enemyPlayer = playerIter.next();
        final Predicate<Unit> enemyPlane = Matches.unitIsAir().and(Matches.unitIsOwnedBy(enemyPlayer)).and(Matches.unitCanMove());
        final Predicate<Unit> enemyTransport = Matches.unitIsOwnedBy(enemyPlayer).and(Matches.unitIsSea()).and(Matches.unitIsTransport()).and(Matches.unitCanMove());
        final Predicate<Unit> enemyShip = Matches.unitIsOwnedBy(enemyPlayer).and(Matches.unitIsSea()).and(Matches.unitCanMove());
        final Predicate<Unit> enemyTransportable = Matches.unitIsOwnedBy(enemyPlayer).and(Matches.unitCanBeTransported()).and(Matches.unitIsNotAa()).and(Matches.unitCanMove());
        final Predicate<Unit> transport = Matches.unitIsSea().and(Matches.unitIsTransport()).and(Matches.unitCanMove());
        final List<Territory> enemyFighterTerritories = findUnitTerr(data, enemyPlane);
        int maxFighterDistance = 0;
        // and likely player will have at least 1 max move plane.
        for (final Territory enemyFighterTerritory : enemyFighterTerritories) {
            final List<Unit> enemyFighterUnits = enemyFighterTerritory.getUnits().getMatches(enemyPlane);
            maxFighterDistance = Math.max(maxFighterDistance, MoveValidator.getMaxMovement(enemyFighterUnits));
        }
        // must be able to land...we will miss fighters who have a Carrier that can reach same sea zone...C'est la vie
        maxFighterDistance--;
        if (maxFighterDistance < 0) {
            maxFighterDistance = 0;
        }
        final List<Territory> enemyTransportTerritories = findUnitTerr(data, transport);
        int maxTransportDistance = 0;
        for (final Territory enemyTransportTerritory : enemyTransportTerritories) {
            final List<Unit> enemyTransportUnits = enemyTransportTerritory.getUnits().getMatches(transport);
            maxTransportDistance = Math.max(maxTransportDistance, MoveValidator.getMaxMovement(enemyTransportUnits));
        }
        final List<Unit> alreadyLoaded = new ArrayList<>();
        final List<Route> blitzTerrRoutes = new ArrayList<>();
        final List<Territory> checked = new ArrayList<>();
        final List<Unit> enemyWaterUnits = new ArrayList<>();
        for (final Territory t : data.getMap().getNeighbors(location, onWater ? Matches.territoryIsWater() : Matches.territoryIsLand())) {
            final List<Unit> enemies = t.getUnits().getMatches(Matches.unitIsOwnedBy(enemyPlayer));
            enemyWaterUnits.addAll(enemies);
            firstStrength += strength(enemies, true, onWater, transportsFirst);
            checked.add(t);
        }
        if (Matches.territoryIsLand().test(location)) {
            blitzStrength = determineEnemyBlitzStrength(location, blitzTerrRoutes, data, enemyPlayer);
        } else {
            // get ships attack strength
            // old assumed fleets won't split up, new lets them. no biggie.
            // assumes max ship movement is 3.
            // note, both old and new implementations
            // allow units to be calculated that are in
            // territories we have already assaulted
            // this can be easily changed
            final HashSet<Integer> ignore = new HashSet<>();
            ignore.add(1);
            final List<Route> r = new ArrayList<>();
            final List<Unit> ships = findAttackers(location, 3, ignore, enemyPlayer, data, enemyShip, Matches.territoryIsBlockedSea(enemyPlayer, data), r, true);
            secondStrength = strength(ships, true, true, transportsFirst);
            enemyWaterUnits.addAll(ships);
        }
        final List<Unit> attackPlanes = findPlaneAttackersThatCanLand(location, maxFighterDistance, enemyPlayer, data, checked);
        final float airStrength = allAirStrength(attackPlanes);
        if (Matches.territoryHasWaterNeighbor(data).test(location) && Matches.territoryIsLand().test(location)) {
            for (final Territory t4 : data.getMap().getNeighbors(location, maxTransportDistance)) {
                if (!t4.isWater()) {
                    continue;
                }
                for (final Territory waterCheck : waterTerr) {
                    if (enemyPlayer == null) {
                        continue;
                    }
                    final List<Unit> transports = t4.getUnits().getMatches(enemyTransport);
                    if (transports.isEmpty()) {
                        continue;
                    }
                    if (!t4.equals(waterCheck)) {
                        final Route seaRoute = getMaxSeaRoute(data, t4, waterCheck, enemyPlayer, maxTransportDistance);
                        if (seaRoute == null || seaRoute.getEnd() == null || seaRoute.getEnd() != waterCheck) {
                            continue;
                        }
                    }
                    final List<Unit> loadedUnits = new ArrayList<>();
                    int availInf = 0;
                    int availOther = 0;
                    for (final Unit candidateTransport : transports) {
                        final Collection<Unit> thisTransUnits = TransportTracker.transporting(candidateTransport);
                        if (thisTransUnits == null) {
                            availInf += 2;
                            availOther += 1;
                            continue;
                        }
                        int inf = 2;
                        int other = 1;
                        for (final Unit checkUnit : thisTransUnits) {
                            if (Matches.unitIsLandTransportable().test(checkUnit)) {
                                inf--;
                            }
                            if (Matches.unitIsNotLandTransportable().test(checkUnit)) {
                                inf--;
                                other--;
                            }
                            loadedUnits.add(checkUnit);
                        }
                        availInf += inf;
                        availOther += other;
                    }
                    final Set<Territory> transNeighbors = data.getMap().getNeighbors(t4, Matches.isTerritoryAllied(enemyPlayer, data));
                    for (final Territory transNeighbor : transNeighbors) {
                        final List<Unit> transUnits = transNeighbor.getUnits().getMatches(enemyTransportable);
                        transUnits.removeAll(alreadyLoaded);
                        final List<Unit> availTransUnits = sortTransportUnits(transUnits);
                        for (final Unit transUnit : availTransUnits) {
                            if (availInf > 0 && Matches.unitIsLandTransportable().test(transUnit)) {
                                availInf--;
                                loadedUnits.add(transUnit);
                                alreadyLoaded.add(transUnit);
                            }
                            if (availInf > 0 && availOther > 0 && Matches.unitIsNotLandTransportable().test(transUnit)) {
                                availInf--;
                                availOther--;
                                loadedUnits.add(transUnit);
                                alreadyLoaded.add(transUnit);
                            }
                        }
                    }
                    seaStrength += strength(loadedUnits, true, false, transportsFirst);
                    break;
                }
            }
        }
        strength = seaStrength + blitzStrength + firstStrength + secondStrength;
        if (strength > 0.0F) {
            strength += airStrength;
        }
        if (onWater) {
            final Iterator<Unit> enemyWaterUnitsIter = enemyWaterUnits.iterator();
            while (enemyWaterUnitsIter.hasNext() && !nonTransportsInAttack) {
                if (Matches.unitIsNotTransport().test(enemyWaterUnitsIter.next())) {
                    nonTransportsInAttack = true;
                }
            }
        }
        if (!nonTransportsInAttack) {
            strength = 0.0F;
        }
        enemyPlayerAttackMap.put(enemyPlayer, strength);
    }
    float maxStrength = 0.0F;
    for (final PlayerID enemyPlayerCandidate : enemyPlayers) {
        if (enemyPlayerAttackMap.get(enemyPlayerCandidate) > maxStrength) {
            enemyPlayer = enemyPlayerCandidate;
            maxStrength = enemyPlayerAttackMap.get(enemyPlayerCandidate);
        }
    }
    for (final PlayerID enemyPlayerCandidate : enemyPlayers) {
        if (enemyPlayer != enemyPlayerCandidate) {
            // give 40% of other players...this is will affect a lot of decisions by AI
            maxStrength += enemyPlayerAttackMap.get(enemyPlayerCandidate) * 0.40F;
        }
    }
    return maxStrength;
}
Also used : PlayerID(games.strategy.engine.data.PlayerID) Territory(games.strategy.engine.data.Territory) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Unit(games.strategy.engine.data.Unit) Route(games.strategy.engine.data.Route) HashSet(java.util.HashSet)

Example 18 with Route

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

the class ProBattleUtils method territoryHasLocalNavalSuperiority.

public static boolean territoryHasLocalNavalSuperiority(final Territory t, final PlayerID player, final Map<Territory, ProPurchaseTerritory> purchaseTerritories, final List<Unit> unitsToPlace) {
    final GameData data = ProData.getData();
    int landDistance = ProUtils.getClosestEnemyLandTerritoryDistanceOverWater(data, player, t);
    if (landDistance <= 0) {
        landDistance = 10;
    }
    final int enemyDistance = Math.max(3, (landDistance + 1));
    final Set<Territory> nearbyTerritories = data.getMap().getNeighbors(t, enemyDistance);
    final List<Territory> nearbyLandTerritories = CollectionUtils.getMatches(nearbyTerritories, Matches.territoryIsLand());
    final Set<Territory> nearbyEnemySeaTerritories = data.getMap().getNeighbors(t, enemyDistance, Matches.territoryIsWater());
    nearbyEnemySeaTerritories.add(t);
    final int alliedDistance = (enemyDistance + 1) / 2;
    final Set<Territory> nearbyAlliedSeaTerritories = data.getMap().getNeighbors(t, alliedDistance, Matches.territoryIsWater());
    nearbyAlliedSeaTerritories.add(t);
    final List<Unit> enemyUnitsInLandTerritories = new ArrayList<>();
    for (final Territory nearbyLandTerritory : nearbyLandTerritories) {
        enemyUnitsInLandTerritories.addAll(nearbyLandTerritory.getUnits().getMatches(ProMatches.unitIsEnemyAir(player, data)));
    }
    final List<Unit> enemyUnitsInSeaTerritories = new ArrayList<>();
    for (final Territory nearbySeaTerritory : nearbyEnemySeaTerritories) {
        final List<Unit> enemySeaUnits = nearbySeaTerritory.getUnits().getMatches(ProMatches.unitIsEnemyNotLand(player, data));
        if (enemySeaUnits.isEmpty()) {
            continue;
        }
        final Route route = data.getMap().getRoute_IgnoreEnd(t, nearbySeaTerritory, Matches.territoryIsWater());
        if (route == null) {
            continue;
        }
        if (MoveValidator.validateCanal(route, enemySeaUnits, enemySeaUnits.get(0).getOwner(), data) != null) {
            continue;
        }
        final int routeLength = route.numberOfSteps();
        if (routeLength <= enemyDistance) {
            enemyUnitsInSeaTerritories.addAll(enemySeaUnits);
        }
    }
    final List<Unit> alliedUnitsInSeaTerritories = new ArrayList<>();
    final List<Unit> myUnitsInSeaTerritories = new ArrayList<>();
    for (final Territory nearbySeaTerritory : nearbyAlliedSeaTerritories) {
        myUnitsInSeaTerritories.addAll(nearbySeaTerritory.getUnits().getMatches(ProMatches.unitIsOwnedNotLand(player)));
        myUnitsInSeaTerritories.addAll(ProPurchaseUtils.getPlaceUnits(nearbySeaTerritory, purchaseTerritories));
        alliedUnitsInSeaTerritories.addAll(nearbySeaTerritory.getUnits().getMatches(ProMatches.unitIsAlliedNotOwned(player, data)));
    }
    ProLogger.trace(t + ", enemyDistance=" + enemyDistance + ", alliedDistance=" + alliedDistance + ", enemyAirUnits=" + enemyUnitsInLandTerritories + ", enemySeaUnits=" + enemyUnitsInSeaTerritories + ", mySeaUnits=" + myUnitsInSeaTerritories);
    // Find current naval defense strength
    final List<Unit> myUnits = new ArrayList<>(myUnitsInSeaTerritories);
    myUnits.addAll(unitsToPlace);
    myUnits.addAll(alliedUnitsInSeaTerritories);
    final List<Unit> enemyAttackers = new ArrayList<>(enemyUnitsInSeaTerritories);
    enemyAttackers.addAll(enemyUnitsInLandTerritories);
    final double defenseStrengthDifference = estimateStrengthDifference(t, enemyAttackers, myUnits);
    ProLogger.trace(t + ", current enemy naval attack strengthDifference=" + defenseStrengthDifference + ", enemySize=" + enemyAttackers.size() + ", alliedSize=" + myUnits.size());
    // Find current naval attack strength
    double attackStrengthDifference = estimateStrengthDifference(t, myUnits, enemyUnitsInSeaTerritories);
    attackStrengthDifference += 0.5 * estimateStrengthDifference(t, alliedUnitsInSeaTerritories, enemyUnitsInSeaTerritories);
    ProLogger.trace(t + ", current allied naval attack strengthDifference=" + attackStrengthDifference + ", alliedSize=" + myUnits.size() + ", enemySize=" + enemyUnitsInSeaTerritories.size());
    // If I have naval attack/defense superiority then break
    return (defenseStrengthDifference < 50 && attackStrengthDifference > 50);
}
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) ArrayList(java.util.ArrayList) Unit(games.strategy.engine.data.Unit) Route(games.strategy.engine.data.Route)

Example 19 with Route

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

the class ProMoveUtils method doMove.

public static void doMove(final List<Collection<Unit>> moveUnits, final List<Route> moveRoutes, final List<Collection<Unit>> transportsToLoad, final IMoveDelegate moveDel) {
    final GameData data = ProData.getData();
    // Group non-amphib units of the same type moving on the same route
    if (transportsToLoad == null) {
        for (int i = 0; i < moveRoutes.size(); i++) {
            final Route r = moveRoutes.get(i);
            for (int j = i + 1; j < moveRoutes.size(); j++) {
                final Route r2 = moveRoutes.get(j);
                if (r.equals(r2)) {
                    moveUnits.get(j).addAll(moveUnits.get(i));
                    moveUnits.remove(i);
                    moveRoutes.remove(i);
                    i--;
                    break;
                }
            }
        }
    }
    // Move units
    for (int i = 0; i < moveRoutes.size(); i++) {
        if (!ProData.isSimulation) {
            ProUtils.pause();
        }
        if (moveRoutes.get(i) == null || moveRoutes.get(i).getEnd() == null || moveRoutes.get(i).getStart() == null) {
            ProLogger.warn(data.getSequence().getRound() + "-" + data.getSequence().getStep().getName() + ": route not valid " + moveRoutes.get(i) + " units: " + moveUnits.get(i));
            continue;
        }
        final String result;
        if (transportsToLoad == null || transportsToLoad.get(i) == null) {
            result = moveDel.move(moveUnits.get(i), moveRoutes.get(i));
        } else {
            result = moveDel.move(moveUnits.get(i), moveRoutes.get(i), transportsToLoad.get(i));
        }
        if (result != null) {
            ProLogger.warn(data.getSequence().getRound() + "-" + data.getSequence().getStep().getName() + ": could not move " + moveUnits.get(i) + " over " + moveRoutes.get(i) + " because: " + result);
        }
    }
}
Also used : GameData(games.strategy.engine.data.GameData) Route(games.strategy.engine.data.Route)

Example 20 with Route

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

the class ProMoveUtils method calculateMoveRoutes.

public static void calculateMoveRoutes(final PlayerID player, final List<Collection<Unit>> moveUnits, final List<Route> moveRoutes, final Map<Territory, ProTerritory> attackMap, final boolean isCombatMove) {
    final GameData data = ProData.getData();
    // Find all amphib units
    final Set<Unit> amphibUnits = attackMap.values().stream().map(ProTerritory::getAmphibAttackMap).map(Map::entrySet).flatMap(Collection::stream).flatMap(e -> Stream.concat(Stream.of(e.getKey()), e.getValue().stream())).collect(Collectors.toSet());
    // Loop through all territories to attack
    for (final Territory t : attackMap.keySet()) {
        // Loop through each unit that is attacking the current territory
        for (final Unit u : attackMap.get(t).getUnits()) {
            // Skip amphib units
            if (amphibUnits.contains(u)) {
                continue;
            }
            // Skip if unit is already in move to territory
            final Territory startTerritory = ProData.unitTerritoryMap.get(u);
            if (startTerritory == null || startTerritory.equals(t)) {
                continue;
            }
            // Add unit to move list
            final List<Unit> unitList = new ArrayList<>();
            unitList.add(u);
            moveUnits.add(unitList);
            // If carrier has dependent allied fighters then move them too
            if (Matches.unitIsCarrier().test(u)) {
                final Map<Unit, Collection<Unit>> carrierMustMoveWith = MoveValidator.carrierMustMoveWith(startTerritory.getUnits().getUnits(), startTerritory, data, player);
                if (carrierMustMoveWith.containsKey(u)) {
                    unitList.addAll(carrierMustMoveWith.get(u));
                }
            }
            // Determine route and add to move list
            Route route = null;
            if (unitList.stream().anyMatch(Matches.unitIsSea())) {
                // Sea unit (including carriers with planes)
                route = data.getMap().getRoute_IgnoreEnd(startTerritory, t, ProMatches.territoryCanMoveSeaUnitsThrough(player, data, isCombatMove));
            } else if (!unitList.isEmpty() && unitList.stream().allMatch(Matches.unitIsLand())) {
                // Land unit
                route = data.getMap().getRoute_IgnoreEnd(startTerritory, t, ProMatches.territoryCanMoveLandUnitsThrough(player, data, u, startTerritory, isCombatMove, new ArrayList<>()));
            } else if (!unitList.isEmpty() && unitList.stream().allMatch(Matches.unitIsAir())) {
                // Air unit
                route = data.getMap().getRoute_IgnoreEnd(startTerritory, t, ProMatches.territoryCanMoveAirUnitsAndNoAa(player, data, isCombatMove));
            }
            if (route == null) {
                ProLogger.warn(data.getSequence().getRound() + "-" + data.getSequence().getStep().getName() + ": route is null " + startTerritory + " to " + t + ", units=" + unitList);
            }
            moveRoutes.add(route);
        }
    }
}
Also used : Unit(games.strategy.engine.data.Unit) Collection(java.util.Collection) Set(java.util.Set) Territory(games.strategy.engine.data.Territory) Collectors(java.util.stream.Collectors) ArrayList(java.util.ArrayList) ProTerritory(games.strategy.triplea.ai.pro.data.ProTerritory) ProLogger(games.strategy.triplea.ai.pro.logging.ProLogger) ProData(games.strategy.triplea.ai.pro.ProData) GameData(games.strategy.engine.data.GameData) Route(games.strategy.engine.data.Route) List(java.util.List) TransportTracker(games.strategy.triplea.delegate.TransportTracker) Stream(java.util.stream.Stream) PlayerID(games.strategy.engine.data.PlayerID) IMoveDelegate(games.strategy.triplea.delegate.remote.IMoveDelegate) Matches(games.strategy.triplea.delegate.Matches) MoveValidator(games.strategy.triplea.delegate.MoveValidator) Map(java.util.Map) TripleAUnit(games.strategy.triplea.TripleAUnit) Collections(java.util.Collections) Territory(games.strategy.engine.data.Territory) ProTerritory(games.strategy.triplea.ai.pro.data.ProTerritory) GameData(games.strategy.engine.data.GameData) ProTerritory(games.strategy.triplea.ai.pro.data.ProTerritory) ArrayList(java.util.ArrayList) Collection(java.util.Collection) Unit(games.strategy.engine.data.Unit) TripleAUnit(games.strategy.triplea.TripleAUnit) Route(games.strategy.engine.data.Route)

Aggregations

Route (games.strategy.engine.data.Route)200 Test (org.junit.jupiter.api.Test)148 Territory (games.strategy.engine.data.Territory)132 Unit (games.strategy.engine.data.Unit)84 UnitType (games.strategy.engine.data.UnitType)83 ITestDelegateBridge (games.strategy.engine.data.ITestDelegateBridge)77 TripleAUnit (games.strategy.triplea.TripleAUnit)70 IntegerMap (games.strategy.util.IntegerMap)69 PlayerID (games.strategy.engine.data.PlayerID)64 ArrayList (java.util.ArrayList)44 GameData (games.strategy.engine.data.GameData)29 ScriptedRandomSource (games.strategy.engine.random.ScriptedRandomSource)26 HashSet (java.util.HashSet)21 HashMap (java.util.HashMap)20 Collection (java.util.Collection)15 List (java.util.List)12 Set (java.util.Set)12 UnitAttachment (games.strategy.triplea.attachments.UnitAttachment)11 Change (games.strategy.engine.data.Change)10 MoveValidationResult (games.strategy.triplea.delegate.dataObjects.MoveValidationResult)10