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;
}
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;
}
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;
}
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);
}
}
}
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;
}
Aggregations