Search in sources :

Example 66 with IntegerMap

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

the class TuvUtils method getResourceCostsForTuv.

/**
 * Return map where keys are unit types and values are resource costs of that unit type, based on a player.
 * Any production rule that produces multiple units
 * (like artillery in NWO, costs 7 but makes 2 artillery, meaning effective price is 3.5 each)
 * will have their costs rounded up on a per unit basis.
 * Therefore, this map should NOT be used for Purchasing information!
 */
public static Map<PlayerID, Map<UnitType, ResourceCollection>> getResourceCostsForTuv(final GameData data, final boolean includeAverageForMissingUnits) {
    final HashMap<PlayerID, Map<UnitType, ResourceCollection>> result = new LinkedHashMap<>();
    final Map<UnitType, ResourceCollection> average = includeAverageForMissingUnits ? TuvUtils.getResourceCostsForTuvForAllPlayersMergedAndAveraged(data) : new HashMap<>();
    final List<PlayerID> players = data.getPlayerList().getPlayers();
    players.add(PlayerID.NULL_PLAYERID);
    for (final PlayerID p : players) {
        final ProductionFrontier frontier = p.getProductionFrontier();
        // any one will do then
        if (frontier == null) {
            result.put(p, average);
            continue;
        }
        final Map<UnitType, ResourceCollection> current = result.computeIfAbsent(p, k -> new LinkedHashMap<>());
        for (final ProductionRule rule : frontier.getRules()) {
            if (rule == null || rule.getResults() == null || rule.getResults().isEmpty() || rule.getCosts() == null || rule.getCosts().isEmpty()) {
                continue;
            }
            final IntegerMap<NamedAttachable> unitMap = rule.getResults();
            final ResourceCollection costPerGroup = new ResourceCollection(data, rule.getCosts());
            final Set<UnitType> units = new HashSet<>();
            for (final NamedAttachable resourceOrUnit : unitMap.keySet()) {
                if (!(resourceOrUnit instanceof UnitType)) {
                    continue;
                }
                units.add((UnitType) resourceOrUnit);
            }
            if (units.isEmpty()) {
                continue;
            }
            final int totalProduced = unitMap.totalValues();
            if (totalProduced == 1) {
                current.put(units.iterator().next(), costPerGroup);
            } else if (totalProduced > 1) {
                costPerGroup.discount((double) 1 / (double) totalProduced);
                for (final UnitType ut : units) {
                    current.put(ut, costPerGroup);
                }
            }
        }
        // we will add any unit types not in our list, based on the list for everyone
        for (final UnitType ut : average.keySet()) {
            if (!current.keySet().contains(ut)) {
                current.put(ut, average.get(ut));
            }
        }
    }
    result.put(null, average);
    return result;
}
Also used : PlayerID(games.strategy.engine.data.PlayerID) NamedAttachable(games.strategy.engine.data.NamedAttachable) ProductionFrontier(games.strategy.engine.data.ProductionFrontier) LinkedHashMap(java.util.LinkedHashMap) ProductionRule(games.strategy.engine.data.ProductionRule) UnitType(games.strategy.engine.data.UnitType) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) IntegerMap(games.strategy.util.IntegerMap) ResourceCollection(games.strategy.engine.data.ResourceCollection) HashSet(java.util.HashSet)

Example 67 with IntegerMap

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

the class PurchaseDelegate method getUnitRepairs.

private static IntegerMap<Unit> getUnitRepairs(final Map<Unit, IntegerMap<RepairRule>> repairRules) {
    final IntegerMap<Unit> repairMap = new IntegerMap<>();
    for (final Unit u : repairRules.keySet()) {
        final IntegerMap<RepairRule> rules = repairRules.get(u);
        final TreeSet<RepairRule> repRules = new TreeSet<>(repairRuleComparator);
        repRules.addAll(rules.keySet());
        for (final RepairRule repairRule : repRules) {
            final int quantity = rules.getInt(repairRule) * repairRule.getResults().getInt(u.getType());
            repairMap.add(u, quantity);
        }
    }
    return repairMap;
}
Also used : IntegerMap(games.strategy.util.IntegerMap) TreeSet(java.util.TreeSet) RepairRule(games.strategy.engine.data.RepairRule) TripleAUnit(games.strategy.triplea.TripleAUnit) Unit(games.strategy.engine.data.Unit)

Example 68 with IntegerMap

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

the class PurchaseDelegate method purchaseRepair.

@Override
public String purchaseRepair(final Map<Unit, IntegerMap<RepairRule>> repairRules) {
    final IntegerMap<Resource> costs = getRepairCosts(repairRules, player);
    if (!(canAfford(costs, player))) {
        return NOT_ENOUGH_RESOURCES;
    }
    if (!Properties.getDamageFromBombingDoneToUnitsInsteadOfTerritories(getData())) {
        return null;
    }
    // Get the map of the factories that were repaired and how much for each
    final IntegerMap<Unit> repairMap = getUnitRepairs(repairRules);
    if (repairMap.isEmpty()) {
        return null;
    }
    // remove first, since add logs PUs remaining
    final CompositeChange changes = new CompositeChange();
    final Set<Unit> repairUnits = new HashSet<>(repairMap.keySet());
    final IntegerMap<Unit> damageMap = new IntegerMap<>();
    for (final Unit u : repairUnits) {
        final int repairCount = repairMap.getInt(u);
        // Display appropriate damaged/repaired factory and factory damage totals
        if (repairCount > 0) {
            final TripleAUnit taUnit = (TripleAUnit) u;
            final int newDamageTotal = Math.max(0, taUnit.getUnitDamage() - repairCount);
            if (newDamageTotal != taUnit.getUnitDamage()) {
                damageMap.put(u, newDamageTotal);
            }
        }
    }
    if (!damageMap.isEmpty()) {
        changes.add(ChangeFactory.bombingUnitDamage(damageMap));
    }
    // add changes for spent resources
    final String remaining = removeFromPlayer(costs, changes);
    // add history event
    final String transcriptText;
    if (!damageMap.isEmpty()) {
        transcriptText = player.getName() + " repair damage of " + MyFormatter.integerUnitMapToString(repairMap, ", ", "x ", true) + "; " + remaining;
    } else {
        transcriptText = player.getName() + " repair nothing; " + remaining;
    }
    bridge.getHistoryWriter().startEvent(transcriptText, new HashSet<>(damageMap.keySet()));
    // commit changes
    if (!changes.isEmpty()) {
        bridge.addChange(changes);
    }
    return null;
}
Also used : IntegerMap(games.strategy.util.IntegerMap) Resource(games.strategy.engine.data.Resource) TripleAUnit(games.strategy.triplea.TripleAUnit) Unit(games.strategy.engine.data.Unit) CompositeChange(games.strategy.engine.data.CompositeChange) TripleAUnit(games.strategy.triplea.TripleAUnit) HashSet(java.util.HashSet)

Example 69 with IntegerMap

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

the class RandomStartDelegate method setupBoard.

private void setupBoard() {
    final GameData data = getData();
    final boolean randomTerritories = Properties.getTerritoriesAreAssignedRandomly(data);
    final Predicate<Territory> pickableTerritoryMatch = getTerritoryPickableMatch();
    final Predicate<PlayerID> playerCanPickMatch = getPlayerCanPickMatch();
    final List<Territory> allPickableTerritories = CollectionUtils.getMatches(data.getMap().getTerritories(), pickableTerritoryMatch);
    final List<PlayerID> playersCanPick = new ArrayList<>(CollectionUtils.getMatches(data.getPlayerList().getPlayers(), playerCanPickMatch));
    // we need a main event
    if (!playersCanPick.isEmpty()) {
        bridge.getHistoryWriter().startEvent("Assigning Territories");
    }
    // for random:
    final int[] hitRandom = (!randomTerritories ? new int[0] : bridge.getRandom(allPickableTerritories.size(), allPickableTerritories.size(), null, DiceType.ENGINE, "Picking random territories"));
    int i = 0;
    int pos = 0;
    // divvy up territories
    while (!allPickableTerritories.isEmpty() && !playersCanPick.isEmpty()) {
        if (currentPickingPlayer == null || !playersCanPick.contains(currentPickingPlayer)) {
            currentPickingPlayer = playersCanPick.get(0);
        }
        if (!Interruptibles.sleep(250)) {
            return;
        }
        Territory picked;
        if (randomTerritories) {
            pos += hitRandom[i];
            i++;
            final IntegerMap<UnitType> costs = TuvUtils.getCostsForTuv(currentPickingPlayer, data);
            final List<Unit> units = new ArrayList<>(currentPickingPlayer.getUnits().getUnits());
            units.sort(Comparator.comparingInt(unit -> costs.getInt(unit.getType())));
            final Set<Unit> unitsToPlace = new HashSet<>();
            unitsToPlace.add(units.get(0));
            picked = allPickableTerritories.get(pos % allPickableTerritories.size());
            final CompositeChange change = new CompositeChange();
            change.add(ChangeFactory.changeOwner(picked, currentPickingPlayer));
            final Collection<Unit> factoryAndInfrastructure = CollectionUtils.getMatches(unitsToPlace, Matches.unitIsInfrastructure());
            if (!factoryAndInfrastructure.isEmpty()) {
                change.add(OriginalOwnerTracker.addOriginalOwnerChange(factoryAndInfrastructure, currentPickingPlayer));
            }
            change.add(ChangeFactory.removeUnits(currentPickingPlayer, unitsToPlace));
            change.add(ChangeFactory.addUnits(picked, unitsToPlace));
            bridge.getHistoryWriter().addChildToEvent(currentPickingPlayer.getName() + " receives territory " + picked.getName() + " with units " + MyFormatter.unitsToTextNoOwner(unitsToPlace), picked);
            bridge.addChange(change);
        } else {
            Set<Unit> unitsToPlace;
            while (true) {
                final Tuple<Territory, Set<Unit>> pick = getRemotePlayer(currentPickingPlayer).pickTerritoryAndUnits(new ArrayList<>(allPickableTerritories), new ArrayList<>(currentPickingPlayer.getUnits().getUnits()), UNITS_PER_PICK);
                picked = pick.getFirst();
                unitsToPlace = pick.getSecond();
                if (!allPickableTerritories.contains(picked) || !currentPickingPlayer.getUnits().getUnits().containsAll(unitsToPlace) || unitsToPlace.size() > UNITS_PER_PICK || (unitsToPlace.size() < UNITS_PER_PICK && unitsToPlace.size() < currentPickingPlayer.getUnits().getUnits().size())) {
                    getRemotePlayer(currentPickingPlayer).reportMessage("Chosen territory or units invalid!", "Chosen territory or units invalid!");
                } else {
                    break;
                }
            }
            final CompositeChange change = new CompositeChange();
            change.add(ChangeFactory.changeOwner(picked, currentPickingPlayer));
            final Collection<Unit> factoryAndInfrastructure = CollectionUtils.getMatches(unitsToPlace, Matches.unitIsInfrastructure());
            if (!factoryAndInfrastructure.isEmpty()) {
                change.add(OriginalOwnerTracker.addOriginalOwnerChange(factoryAndInfrastructure, currentPickingPlayer));
            }
            change.add(ChangeFactory.removeUnits(currentPickingPlayer, unitsToPlace));
            change.add(ChangeFactory.addUnits(picked, unitsToPlace));
            bridge.getHistoryWriter().addChildToEvent(currentPickingPlayer.getName() + " picks territory " + picked.getName() + " and places in it " + MyFormatter.unitsToTextNoOwner(unitsToPlace), unitsToPlace);
            bridge.addChange(change);
        }
        allPickableTerritories.remove(picked);
        final PlayerID lastPlayer = currentPickingPlayer;
        currentPickingPlayer = getNextPlayer(playersCanPick, currentPickingPlayer);
        if (!playerCanPickMatch.test(lastPlayer)) {
            playersCanPick.remove(lastPlayer);
        }
        if (playersCanPick.isEmpty()) {
            currentPickingPlayer = null;
        }
    }
    // place any remaining units
    while (!playersCanPick.isEmpty()) {
        if (currentPickingPlayer == null || !playersCanPick.contains(currentPickingPlayer)) {
            currentPickingPlayer = playersCanPick.get(0);
        }
        final List<Territory> territoriesToPickFrom = data.getMap().getTerritoriesOwnedBy(currentPickingPlayer);
        Territory picked;
        Set<Unit> unitsToPlace;
        while (true) {
            final Tuple<Territory, Set<Unit>> pick = getRemotePlayer(currentPickingPlayer).pickTerritoryAndUnits(new ArrayList<>(territoriesToPickFrom), new ArrayList<>(currentPickingPlayer.getUnits().getUnits()), UNITS_PER_PICK);
            picked = pick.getFirst();
            unitsToPlace = pick.getSecond();
            if (!territoriesToPickFrom.contains(picked) || !currentPickingPlayer.getUnits().getUnits().containsAll(unitsToPlace) || unitsToPlace.size() > UNITS_PER_PICK || (unitsToPlace.size() < UNITS_PER_PICK && unitsToPlace.size() < currentPickingPlayer.getUnits().getUnits().size())) {
                getRemotePlayer(currentPickingPlayer).reportMessage("Chosen territory or units invalid!", "Chosen territory or units invalid!");
            } else {
                break;
            }
        }
        final CompositeChange change = new CompositeChange();
        final Collection<Unit> factoryAndInfrastructure = CollectionUtils.getMatches(unitsToPlace, Matches.unitIsInfrastructure());
        if (!factoryAndInfrastructure.isEmpty()) {
            change.add(OriginalOwnerTracker.addOriginalOwnerChange(factoryAndInfrastructure, currentPickingPlayer));
        }
        change.add(ChangeFactory.removeUnits(currentPickingPlayer, unitsToPlace));
        change.add(ChangeFactory.addUnits(picked, unitsToPlace));
        bridge.getHistoryWriter().addChildToEvent(currentPickingPlayer.getName() + " places " + MyFormatter.unitsToTextNoOwner(unitsToPlace) + " in territory " + picked.getName(), unitsToPlace);
        bridge.addChange(change);
        final PlayerID lastPlayer = currentPickingPlayer;
        currentPickingPlayer = getNextPlayer(playersCanPick, currentPickingPlayer);
        if (!playerCanPickMatch.test(lastPlayer)) {
            playersCanPick.remove(lastPlayer);
        }
        if (playersCanPick.isEmpty()) {
            currentPickingPlayer = null;
        }
    }
}
Also used : DiceType(games.strategy.engine.random.IRandomStats.DiceType) IRemote(games.strategy.engine.message.IRemote) Properties(games.strategy.triplea.Properties) TuvUtils(games.strategy.triplea.util.TuvUtils) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) UnitType(games.strategy.engine.data.UnitType) CompositeChange(games.strategy.engine.data.CompositeChange) CollectionUtils(games.strategy.util.CollectionUtils) IntegerMap(games.strategy.util.IntegerMap) Unit(games.strategy.engine.data.Unit) Interruptibles(games.strategy.util.Interruptibles) Predicate(java.util.function.Predicate) Collection(java.util.Collection) Set(java.util.Set) Territory(games.strategy.engine.data.Territory) Serializable(java.io.Serializable) GameData(games.strategy.engine.data.GameData) ChangeFactory(games.strategy.engine.data.changefactory.ChangeFactory) List(java.util.List) Tuple(games.strategy.util.Tuple) PlayerID(games.strategy.engine.data.PlayerID) MyFormatter(games.strategy.triplea.formatter.MyFormatter) MapSupport(games.strategy.triplea.MapSupport) Comparator(java.util.Comparator) PlayerID(games.strategy.engine.data.PlayerID) Territory(games.strategy.engine.data.Territory) GameData(games.strategy.engine.data.GameData) HashSet(java.util.HashSet) Set(java.util.Set) ArrayList(java.util.ArrayList) Unit(games.strategy.engine.data.Unit) UnitType(games.strategy.engine.data.UnitType) CompositeChange(games.strategy.engine.data.CompositeChange) HashSet(java.util.HashSet)

Example 70 with IntegerMap

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

the class UnitComparator method getIncreasingCapacityComparator.

public static Comparator<Unit> getIncreasingCapacityComparator(final List<Unit> transports) {
    // this makes it more efficient
    final IntegerMap<Unit> capacityMap = new IntegerMap<>(transports.size() + 1, 1);
    for (final Unit transport : transports) {
        final Collection<Unit> transporting = TripleAUnit.get(transport).getTransporting();
        capacityMap.add(transport, TransportUtils.getTransportCost(transporting));
    }
    return Comparator.comparingInt(capacityMap::getInt);
}
Also used : IntegerMap(games.strategy.util.IntegerMap) Unit(games.strategy.engine.data.Unit) TripleAUnit(games.strategy.triplea.TripleAUnit)

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