Search in sources :

Example 6 with IntegerMap

use of games.strategy.util.IntegerMap in project triplea by triplea-game.

the class AbstractPlaceDelegate method getMaxUnitsToBePlacedMap.

/**
 * Returns -1 somewhere in the map if can place unlimited units.
 */
protected IntegerMap<Territory> getMaxUnitsToBePlacedMap(final Collection<Unit> units, final Territory to, final PlayerID player, final boolean countSwitchedProductionToNeighbors) {
    final IntegerMap<Territory> maxUnitsToBePlacedMap = new IntegerMap<>();
    final List<Territory> producers = getAllProducers(to, player, units);
    if (producers.isEmpty()) {
        return maxUnitsToBePlacedMap;
    }
    producers.sort(getBestProducerComparator(to, units, player));
    final Collection<Territory> notUsableAsOtherProducers = new ArrayList<>(producers);
    final Map<Territory, Integer> currentAvailablePlacementForOtherProducers = new HashMap<>();
    for (final Territory producerTerritory : producers) {
        final Collection<Unit> unitsCanBePlacedByThisProducer = (isUnitPlacementRestrictions() ? CollectionUtils.getMatches(units, unitWhichRequiresUnitsHasRequiredUnits(producerTerritory, true)) : new ArrayList<>(units));
        final int prodT = getMaxUnitsToBePlacedFrom(producerTerritory, unitsCanBePlacedByThisProducer, to, player, countSwitchedProductionToNeighbors, notUsableAsOtherProducers, currentAvailablePlacementForOtherProducers);
        maxUnitsToBePlacedMap.put(producerTerritory, prodT);
    }
    return maxUnitsToBePlacedMap;
}
Also used : IntegerMap(games.strategy.util.IntegerMap) 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)

Example 7 with IntegerMap

use of games.strategy.util.IntegerMap in project triplea by triplea-game.

the class AbstractPlaceDelegate method howManyOfEachConstructionCanPlace.

/**
 * @param to
 *        referring territory.
 * @param units
 *        units to place
 * @param player
 *        PlayerID
 * @return an empty IntegerMap if you can't produce any constructions (will never return null)
 */
public IntegerMap<String> howManyOfEachConstructionCanPlace(final Territory to, final Territory producer, final Collection<Unit> units, final PlayerID player) {
    // constructions can ONLY be produced BY the same territory that they are going into!
    if (!to.equals(producer) || units == null || units.isEmpty() || units.stream().noneMatch(Matches.unitIsConstruction())) {
        return new IntegerMap<>();
    }
    final Collection<Unit> unitsAtStartOfTurnInTo = unitsAtStartOfStepInTerritory(to);
    final Collection<Unit> unitsInTo = to.getUnits().getUnits();
    final Collection<Unit> unitsPlacedAlready = getAlreadyProduced(to);
    // build an integer map of each unit we have in our list of held units, as well as integer maps for maximum units
    // and units per turn
    final IntegerMap<String> unitMapHeld = new IntegerMap<>();
    final IntegerMap<String> unitMapMaxType = new IntegerMap<>();
    final IntegerMap<String> unitMapTypePerTurn = new IntegerMap<>();
    final int maxFactory = Properties.getFactoriesPerCountry(getData());
    // Can be null!
    final TerritoryAttachment terrAttachment = TerritoryAttachment.get(to);
    int toProduction = 0;
    if (terrAttachment != null) {
        toProduction = terrAttachment.getProduction();
    }
    for (final Unit currentUnit : CollectionUtils.getMatches(units, Matches.unitIsConstruction())) {
        final UnitAttachment ua = UnitAttachment.get(currentUnit.getType());
        // account for any unit placement restrictions by territory
        if (isUnitPlacementRestrictions()) {
            final String[] terrs = ua.getUnitPlacementRestrictions();
            final Collection<Territory> listedTerrs = getListedTerritories(terrs);
            if (listedTerrs.contains(to)) {
                continue;
            }
            if (ua.getCanOnlyBePlacedInTerritoryValuedAtX() != -1 && ua.getCanOnlyBePlacedInTerritoryValuedAtX() > toProduction) {
                continue;
            }
            if (unitWhichRequiresUnitsHasRequiredUnits(to, false).negate().test(currentUnit)) {
                continue;
            }
        }
        // remove any units that require other units to be consumed on creation (veqryn)
        if (Matches.unitConsumesUnitsOnCreation().test(currentUnit) && Matches.unitWhichConsumesUnitsHasRequiredUnits(unitsAtStartOfTurnInTo).negate().test(currentUnit)) {
            continue;
        }
        unitMapHeld.add(ua.getConstructionType(), 1);
        unitMapTypePerTurn.put(ua.getConstructionType(), ua.getConstructionsPerTerrPerTypePerTurn());
        if (ua.getConstructionType().equals(Constants.CONSTRUCTION_TYPE_FACTORY)) {
            unitMapMaxType.put(ua.getConstructionType(), maxFactory);
        } else {
            unitMapMaxType.put(ua.getConstructionType(), ua.getMaxConstructionsPerTypePerTerr());
        }
    }
    final boolean moreWithoutFactory = Properties.getMoreConstructionsWithoutFactory(getData());
    final boolean moreWithFactory = Properties.getMoreConstructionsWithFactory(getData());
    final boolean unlimitedConstructions = Properties.getUnlimitedConstructions(getData());
    final boolean wasFactoryThereAtStart = wasOwnedUnitThatCanProduceUnitsOrIsFactoryInTerritoryAtStartOfStep(to, player);
    // build an integer map of each construction unit in the territory
    final IntegerMap<String> unitMapTo = new IntegerMap<>();
    if (unitsInTo.stream().anyMatch(Matches.unitIsConstruction())) {
        for (final Unit currentUnit : CollectionUtils.getMatches(unitsInTo, Matches.unitIsConstruction())) {
            final UnitAttachment ua = UnitAttachment.get(currentUnit.getType());
            /*
         * if (Matches.UnitIsFactory.test(currentUnit) && !ua.getIsConstruction())
         * unitMapTO.add("factory", 1);
         * else
         */
            unitMapTo.add(ua.getConstructionType(), 1);
        }
        // account for units already in the territory, based on max
        for (final String constructionType : unitMapHeld.keySet()) {
            int unitMax = unitMapMaxType.getInt(constructionType);
            if (wasFactoryThereAtStart && !constructionType.equals(Constants.CONSTRUCTION_TYPE_FACTORY) && !constructionType.endsWith("structure")) {
                unitMax = Math.max(Math.max(unitMax, (moreWithFactory ? toProduction : 0)), (unlimitedConstructions ? 10000 : 0));
            }
            if (!wasFactoryThereAtStart && !constructionType.equals(Constants.CONSTRUCTION_TYPE_FACTORY) && !constructionType.endsWith("structure")) {
                unitMax = Math.max(Math.max(unitMax, (moreWithoutFactory ? toProduction : 0)), (unlimitedConstructions ? 10000 : 0));
            }
            unitMapHeld.put(constructionType, Math.max(0, Math.min(unitMax - unitMapTo.getInt(constructionType), unitMapHeld.getInt(constructionType))));
        }
    }
    // deal with already placed units
    for (final Unit currentUnit : CollectionUtils.getMatches(unitsPlacedAlready, Matches.unitIsConstruction())) {
        final UnitAttachment ua = UnitAttachment.get(currentUnit.getType());
        unitMapTypePerTurn.add(ua.getConstructionType(), -1);
    }
    // modify this list based on how many we can place per turn
    final IntegerMap<String> unitsAllowed = new IntegerMap<>();
    for (final String constructionType : unitMapHeld.keySet()) {
        final int unitAllowed = Math.max(0, Math.min(unitMapTypePerTurn.getInt(constructionType), unitMapHeld.getInt(constructionType)));
        if (unitAllowed > 0) {
            unitsAllowed.put(constructionType, unitAllowed);
        }
    }
    // return our integer map
    return unitsAllowed;
}
Also used : IntegerMap(games.strategy.util.IntegerMap) UnitAttachment(games.strategy.triplea.attachments.UnitAttachment) Territory(games.strategy.engine.data.Territory) TerritoryAttachment(games.strategy.triplea.attachments.TerritoryAttachment) TripleAUnit(games.strategy.triplea.TripleAUnit) Unit(games.strategy.engine.data.Unit)

Example 8 with IntegerMap

use of games.strategy.util.IntegerMap 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 9 with IntegerMap

use of games.strategy.util.IntegerMap in project triplea by triplea-game.

the class TriggerAttachment method setRemoveUnits.

private void setRemoveUnits(final String value) throws GameParseException {
    if (value == null) {
        m_removeUnits = null;
        return;
    }
    if (m_removeUnits == null) {
        m_removeUnits = new HashMap<>();
    }
    final String[] s = value.split(":");
    if (s.length < 1) {
        throw new GameParseException("Empty removeUnits list" + thisErrorMsg());
    }
    int count;
    int i = 0;
    try {
        count = getInt(s[0]);
        i++;
    } catch (final Exception e) {
        count = 1;
    }
    if (s.length < 1 || (s.length == 1 && count != -1)) {
        throw new GameParseException("Empty removeUnits list" + thisErrorMsg());
    }
    final Collection<Territory> territories = new ArrayList<>();
    final Territory terr = getData().getMap().getTerritory(s[i]);
    if (terr == null) {
        if (s[i].equalsIgnoreCase("all")) {
            territories.addAll(getData().getMap().getTerritories());
        } else {
            throw new GameParseException("Territory does not exist " + s[i] + thisErrorMsg());
        }
    } else {
        territories.add(terr);
    }
    i++;
    final IntegerMap<UnitType> map = new IntegerMap<>();
    for (; i < s.length; i++) {
        final Collection<UnitType> types = new ArrayList<>();
        final UnitType tp = getData().getUnitTypeList().getUnitType(s[i]);
        if (tp == null) {
            if (s[i].equalsIgnoreCase("all")) {
                types.addAll(getData().getUnitTypeList().getAllUnitTypes());
            } else {
                throw new GameParseException("UnitType does not exist " + s[i] + thisErrorMsg());
            }
        } else {
            types.add(tp);
        }
        for (final UnitType type : types) {
            map.add(type, count);
        }
    }
    for (final Territory t : territories) {
        if (m_removeUnits.containsKey(t)) {
            map.add(m_removeUnits.get(t));
        }
        m_removeUnits.put(t, map);
    }
}
Also used : IntegerMap(games.strategy.util.IntegerMap) Territory(games.strategy.engine.data.Territory) ArrayList(java.util.ArrayList) GameParseException(games.strategy.engine.data.GameParseException) GameParseException(games.strategy.engine.data.GameParseException) UnitType(games.strategy.engine.data.UnitType)

Example 10 with IntegerMap

use of games.strategy.util.IntegerMap in project triplea by triplea-game.

the class MoveDelegate method repairMultipleHitPointUnits.

static void repairMultipleHitPointUnits(final IDelegateBridge bridge, final PlayerID player) {
    final GameData data = bridge.getData();
    final boolean repairOnlyOwn = Properties.getBattleshipsRepairAtBeginningOfRound(bridge.getData());
    final Predicate<Unit> damagedUnits = Matches.unitHasMoreThanOneHitPointTotal().and(Matches.unitHasTakenSomeDamage());
    final Predicate<Unit> damagedUnitsOwned = damagedUnits.and(Matches.unitIsOwnedBy(player));
    final Map<Territory, Set<Unit>> damagedMap = new HashMap<>();
    for (final Territory current : data.getMap().getTerritories()) {
        final Set<Unit> damaged;
        if (!Properties.getTwoHitPointUnitsRequireRepairFacilities(data)) {
            damaged = new HashSet<>(current.getUnits().getMatches(repairOnlyOwn ? damagedUnitsOwned : damagedUnits));
        } else {
            damaged = new HashSet<>(current.getUnits().getMatches(damagedUnitsOwned.and(Matches.unitCanBeRepairedByFacilitiesInItsTerritory(current, player, data))));
        }
        if (!damaged.isEmpty()) {
            damagedMap.put(current, damaged);
        }
    }
    if (damagedMap.isEmpty()) {
        return;
    }
    final Map<Unit, Territory> fullyRepaired = new HashMap<>();
    final IntegerMap<Unit> newHitsMap = new IntegerMap<>();
    for (final Entry<Territory, Set<Unit>> entry : damagedMap.entrySet()) {
        for (final Unit u : entry.getValue()) {
            final int repairAmount = getLargestRepairRateForThisUnit(u, entry.getKey(), data);
            final int currentHits = u.getHits();
            final int newHits = Math.max(0, Math.min(currentHits, (currentHits - repairAmount)));
            if (newHits != currentHits) {
                newHitsMap.put(u, newHits);
            }
            if (newHits <= 0) {
                fullyRepaired.put(u, entry.getKey());
            }
        }
    }
    bridge.getHistoryWriter().startEvent(newHitsMap.size() + " " + MyFormatter.pluralize("unit", newHitsMap.size()) + " repaired.", new HashSet<>(newHitsMap.keySet()));
    bridge.addChange(ChangeFactory.unitsHit(newHitsMap));
    // now if damaged includes any carriers that are repairing, and have damaged abilities set for not allowing air
    // units to leave while damaged, we need to remove those air units now
    final Collection<Unit> damagedCarriers = CollectionUtils.getMatches(fullyRepaired.keySet(), Matches.unitHasWhenCombatDamagedEffect(UnitAttachment.UNITSMAYNOTLEAVEALLIEDCARRIER));
    // now cycle through those now-repaired carriers, and remove allied air from being dependent
    final CompositeChange clearAlliedAir = new CompositeChange();
    for (final Unit carrier : damagedCarriers) {
        final CompositeChange change = MustFightBattle.clearTransportedByForAlliedAirOnCarrier(Collections.singleton(carrier), fullyRepaired.get(carrier), carrier.getOwner(), data);
        if (!change.isEmpty()) {
            clearAlliedAir.add(change);
        }
    }
    if (!clearAlliedAir.isEmpty()) {
        bridge.addChange(clearAlliedAir);
    }
    // Check if any repaired units change into different unit types
    for (final Territory territory : damagedMap.keySet()) {
        repairedChangeInto(damagedMap.get(territory), territory, bridge);
    }
}
Also used : IntegerMap(games.strategy.util.IntegerMap) Territory(games.strategy.engine.data.Territory) GameData(games.strategy.engine.data.GameData) HashSet(java.util.HashSet) Set(java.util.Set) HashMap(java.util.HashMap) TripleAUnit(games.strategy.triplea.TripleAUnit) Unit(games.strategy.engine.data.Unit) CompositeChange(games.strategy.engine.data.CompositeChange)

Aggregations

IntegerMap (games.strategy.util.IntegerMap)132 UnitType (games.strategy.engine.data.UnitType)87 Test (org.junit.jupiter.api.Test)73 Route (games.strategy.engine.data.Route)66 Unit (games.strategy.engine.data.Unit)53 Territory (games.strategy.engine.data.Territory)39 ArrayList (java.util.ArrayList)35 PlayerID (games.strategy.engine.data.PlayerID)26 TripleAUnit (games.strategy.triplea.TripleAUnit)24 HashMap (java.util.HashMap)23 HashSet (java.util.HashSet)19 Resource (games.strategy.engine.data.Resource)16 GameData (games.strategy.engine.data.GameData)15 ProductionRule (games.strategy.engine.data.ProductionRule)14 Collection (java.util.Collection)12 List (java.util.List)12 UnitAttachment (games.strategy.triplea.attachments.UnitAttachment)10 Set (java.util.Set)10 RepairRule (games.strategy.engine.data.RepairRule)9 NamedAttachable (games.strategy.engine.data.NamedAttachable)7