Search in sources :

Example 21 with Territory

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

the class AirMovementValidator method populateStaticAlliedAndBuildingCarrierCapacity.

private static IntegerMap<Territory> populateStaticAlliedAndBuildingCarrierCapacity(final List<Territory> landingSpots, final Map<Unit, Collection<Unit>> movedCarriersAndTheirFighters, final PlayerID player, final GameData data) {
    final IntegerMap<Territory> startingSpace = new IntegerMap<>();
    final Predicate<Unit> carrierAlliedNotOwned = Matches.unitIsOwnedBy(player).negate().and(Matches.isUnitAllied(player, data)).and(Matches.unitIsCarrier());
    // final Predicate<Unit> airAlliedNotOwned = new CompositeMatchAnd<Unit>(Matches.unitIsOwnedBy(player).negate(),
    // Matches.isUnitAllied(player, data), Matches.unitIsAir(), Matches.unitCanLandOnCarrier());
    final boolean landAirOnNewCarriers = AirThatCantLandUtil.isLhtrCarrierProduction(data) || AirThatCantLandUtil.isLandExistingFightersOnNewCarriers(data);
    // final boolean areNeutralsPassableByAir = areNeutralsPassableByAir(data);
    final List<Unit> carriersInProductionQueue = player.getUnits().getMatches(Matches.unitIsCarrier());
    for (final Territory t : landingSpots) {
        if (landAirOnNewCarriers && !carriersInProductionQueue.isEmpty()) {
            if (Matches.territoryIsWater().test(t) && Matches.territoryHasOwnedAtBeginningOfTurnIsFactoryOrCanProduceUnitsNeighbor(data, player).test(t)) {
                // TODO: Here we are assuming that this factory can produce all of the carriers. Actually it might not be able
                // to produce any
                // carriers (because of complex requires units coding) or because of unit damage or maximum production.
                // TODO: Here we are also assuming that the first territory we find that has an adjacent factory is the
                // closest one in terms of
                // unit movement. We have sorted the list of territories so this IS the closest in terms of steps, but each
                // unit may have specific
                // movement allowances for different terrain or some bullshit like that.
                final int producedCarrierCapacity = carrierCapacity(carriersInProductionQueue, t);
                startingSpace.add(t, producedCarrierCapacity);
                carriersInProductionQueue.clear();
            }
        }
        final Collection<Unit> alliedCarriers = t.getUnits().getMatches(carrierAlliedNotOwned);
        alliedCarriers.removeAll(movedCarriersAndTheirFighters.keySet());
        // Collection<Unit> alliedAir = t.getUnits().getMatches(airAlliedNotOwned);
        final int alliedCarrierCapacity = carrierCapacity(alliedCarriers, t);
        startingSpace.add(t, alliedCarrierCapacity);
    }
    return startingSpace;
}
Also used : IntegerMap(games.strategy.util.IntegerMap) Territory(games.strategy.engine.data.Territory) TripleAUnit(games.strategy.triplea.TripleAUnit) Unit(games.strategy.engine.data.Unit)

Example 22 with Territory

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

the class AirMovementValidator method validateAirCanLand.

// TODO: this class does a pretty good job already, but could be improved by having the carriers that are potentially
// moved also look for
// any owned air units that are in sea zones without carriers. these would be air units that have already been moved
// this turn, and
// therefore would need pickup.
static MoveValidationResult validateAirCanLand(final GameData data, final Collection<Unit> units, final Route route, final PlayerID player, final MoveValidationResult result) {
    // First check if we even need to check
    if (// Edit Mode, no need to check
    getEditMode(data) || // No Airunits, nothing to check
    units.stream().noneMatch(Matches.unitIsAir()) || // if there are no steps, we didn't move, so it is always OK!
    route.hasNoSteps() || // we can land at the end, nothing left to check
    Matches.airCanLandOnThisAlliedNonConqueredLandTerritory(player, data).test(route.getEnd()) || // we do not do any validation at all, cus they can all die and we don't care
    isKamikazeAircraft(data)) {
        return result;
    }
    // Find which aircraft cannot find friendly land to land on
    final Collection<Unit> ownedAirThatMustLandOnCarriers = getAirThatMustLandOnCarriers(data, getAirUnitsToValidate(units, route, player), route, result);
    if (ownedAirThatMustLandOnCarriers.isEmpty()) {
        // we are done, everything can find a place to land
        return result;
    }
    final Territory routeEnd = route.getEnd();
    final Territory routeStart = route.getStart();
    // we cannot forget to account for allied air at our location already
    final Predicate<Unit> airAlliedNotOwned = Matches.unitIsOwnedBy(player).negate().and(Matches.isUnitAllied(player, data)).and(Matches.unitIsAir()).and(Matches.unitCanLandOnCarrier());
    final HashSet<Unit> airThatMustLandOnCarriersHash = new HashSet<>();
    airThatMustLandOnCarriersHash.addAll(CollectionUtils.getMatches(routeEnd.getUnits().getUnits(), airAlliedNotOwned));
    airThatMustLandOnCarriersHash.addAll(CollectionUtils.getMatches(units, airAlliedNotOwned));
    // now we must see if we also need to account for units (allied cargo) that are moving with our carriers, if we have
    // selected any carriers
    final Collection<Unit> movingCarriersAtStartLocationBeingMoved = CollectionUtils.getMatches(units, Matches.unitIsCarrier());
    if (!movingCarriersAtStartLocationBeingMoved.isEmpty()) {
        final Map<Unit, Collection<Unit>> carrierToAlliedCargo = MoveValidator.carrierMustMoveWith(units, routeStart, data, player);
        for (final Collection<Unit> alliedAirOnCarrier : carrierToAlliedCargo.values()) {
            airThatMustLandOnCarriersHash.addAll(alliedAirOnCarrier);
        }
    }
    // now we can add our owned air. we add our owned air last because it can be moved, while allied air cannot be. we
    // want the lowest
    // movement to be validated first.
    airThatMustLandOnCarriersHash.addAll(ownedAirThatMustLandOnCarriers);
    final List<Unit> airThatMustLandOnCarriers = new ArrayList<>(airThatMustLandOnCarriersHash);
    // sort the list by shortest range first so those birds will get first pick of landingspots
    airThatMustLandOnCarriers.sort(getLowestToHighestMovementComparatorIncludingUnitsNotYetMoved(route));
    // now we should see if the carriers we are moving with, plus the carriers already there, can handle all our air
    // units (we check ending
    // territories first, separately, because it is special [it includes units in our selection])
    final Collection<Unit> carriersAtEnd = CollectionUtils.getMatches(getFriendly(routeEnd, player, data), Matches.unitIsCarrier());
    carriersAtEnd.addAll(movingCarriersAtStartLocationBeingMoved);
    // to keep track of all carriers, and their fighters, that have moved, so that we do not move them again.
    final Map<Unit, Collection<Unit>> movedCarriersAndTheirFighters = new HashMap<>();
    for (final Unit carrier : carriersAtEnd) {
        movedCarriersAndTheirFighters.put(carrier, new ArrayList<>());
    }
    final Collection<Unit> airNotToConsiderBecauseWeAreValidatingThem = new ArrayList<>(airThatMustLandOnCarriers);
    airThatMustLandOnCarriers.removeAll(whatAirCanLandOnTheseCarriers(carriersAtEnd, airThatMustLandOnCarriers, routeEnd));
    if (airThatMustLandOnCarriers.isEmpty()) {
        return result;
    }
    // we still have air left, so begin calling carriers to come here to pick up the air
    // figure out what is the max distance of
    // our remaining air units
    final int maxMovementLeftForTheseAirUnitsBeingValidated = maxMovementLeftForTheseAirUnitsBeingValidated(airThatMustLandOnCarriers, route, player);
    // figure out what is the max distance
    // of our remaining carrier units
    final int maxMovementLeftForAllOwnedCarriers = maxMovementLeftForAllOwnedCarriers(player, data);
    final List<Territory> landingSpots = new ArrayList<>(Collections.singleton(routeEnd));
    landingSpots.addAll(data.getMap().getNeighbors(routeEnd, maxMovementLeftForTheseAirUnitsBeingValidated, // where can we fly to?
    Matches.airCanFlyOver(player, data, areNeutralsPassableByAir(data))));
    // we only want to consider
    landingSpots.removeAll(CollectionUtils.getMatches(landingSpots, Matches.seaCanMoveOver(player, data).negate()));
    // places we can move carriers to
    landingSpots.sort(getLowestToHighestDistance(routeEnd, Matches.seaCanMoveOver(player, data)));
    final Collection<Territory> potentialCarrierOrigins = new LinkedHashSet<>(landingSpots);
    potentialCarrierOrigins.addAll(data.getMap().getNeighbors(new HashSet<>(landingSpots), maxMovementLeftForAllOwnedCarriers, Matches.seaCanMoveOver(player, data)));
    potentialCarrierOrigins.remove(routeEnd);
    potentialCarrierOrigins.removeAll(CollectionUtils.getMatches(potentialCarrierOrigins, Matches.territoryHasOwnedCarrier(player).negate()));
    // now see if we can move carriers there to pick up
    validateAirCaughtByMovingCarriersAndOwnedAndAlliedAir(result, landingSpots, potentialCarrierOrigins, movedCarriersAndTheirFighters, airThatMustLandOnCarriers, airNotToConsiderBecauseWeAreValidatingThem, player, route, data);
    return result;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) Territory(games.strategy.engine.data.Territory) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) ArrayList(java.util.ArrayList) TripleAUnit(games.strategy.triplea.TripleAUnit) Unit(games.strategy.engine.data.Unit) Collection(java.util.Collection) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet)

Example 23 with Territory

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

the class AirMovementValidator method canFindLand.

private static boolean canFindLand(final GameData data, final Unit unit, final Territory current, final int movementLeft) {
    if (movementLeft <= 0) {
        return false;
    }
    final boolean areNeutralsPassableByAir = areNeutralsPassableByAir(data);
    final PlayerID player = unit.getOwner();
    final List<Territory> possibleSpots = CollectionUtils.getMatches(data.getMap().getNeighbors(current, movementLeft), Matches.airCanLandOnThisAlliedNonConqueredLandTerritory(player, data));
    // have a lot of movement capacity.
    for (final Territory landingSpot : possibleSpots) {
        if (canAirReachThisSpot(data, player, unit, current, movementLeft, landingSpot, areNeutralsPassableByAir)) {
            return true;
        }
    }
    return false;
}
Also used : PlayerID(games.strategy.engine.data.PlayerID) Territory(games.strategy.engine.data.Territory)

Example 24 with Territory

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

the class AirThatCantLandUtil method removeAirThatCantLand.

void removeAirThatCantLand(final PlayerID player, final boolean spareAirInSeaZonesBesideFactories) {
    final GameData data = bridge.getData();
    final GameMap map = data.getMap();
    for (final Territory current : getTerritoriesWhereAirCantLand(player)) {
        final Predicate<Unit> ownedAir = Matches.unitIsAir().and(Matches.alliedUnit(player, data));
        final Collection<Unit> air = current.getUnits().getMatches(ownedAir);
        final boolean hasNeighboringFriendlyFactory = map.getNeighbors(current, Matches.territoryHasAlliedIsFactoryOrCanProduceUnits(data, player)).size() > 0;
        final boolean skip = spareAirInSeaZonesBesideFactories && current.isWater() && hasNeighboringFriendlyFactory;
        if (!skip) {
            removeAirThatCantLand(player, current, air);
        }
    }
}
Also used : Territory(games.strategy.engine.data.Territory) GameData(games.strategy.engine.data.GameData) GameMap(games.strategy.engine.data.GameMap) Unit(games.strategy.engine.data.Unit)

Example 25 with Territory

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

the class TerritoryAttachment method getWhatTerritoriesThisIsUsedInConvoysFor.

public static Set<Territory> getWhatTerritoriesThisIsUsedInConvoysFor(final Territory t, final GameData data) {
    final TerritoryAttachment ta = TerritoryAttachment.get(t);
    if (ta == null || !ta.getConvoyRoute()) {
        return null;
    }
    final Set<Territory> territories = new HashSet<>();
    for (final Territory current : data.getMap().getTerritories()) {
        final TerritoryAttachment cta = TerritoryAttachment.get(current);
        if (cta == null || !cta.getConvoyRoute()) {
            continue;
        }
        if (cta.getConvoyAttached().contains(t)) {
            territories.add(current);
        }
    }
    return territories;
}
Also used : Territory(games.strategy.engine.data.Territory) 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