Search in sources :

Example 6 with NamedAttachable

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

the class TuvUtils method getResourceCostsForTuvForAllPlayersMergedAndAveraged.

/**
 * Return a map where key are unit types and values are the AVERAGED for all players.
 * 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!
 */
private static Map<UnitType, ResourceCollection> getResourceCostsForTuvForAllPlayersMergedAndAveraged(final GameData data) {
    final Map<UnitType, ResourceCollection> average = new HashMap<>();
    final Resource pus;
    data.acquireReadLock();
    try {
        pus = data.getResourceList().getResource(Constants.PUS);
    } finally {
        data.releaseReadLock();
    }
    final IntegerMap<Resource> defaultMap = new IntegerMap<>();
    defaultMap.put(pus, 1);
    final ResourceCollection defaultResources = new ResourceCollection(data, defaultMap);
    final Map<UnitType, List<ResourceCollection>> backups = new HashMap<>();
    final Map<UnitType, ResourceCollection> backupAveraged = new HashMap<>();
    for (final ProductionRule rule : data.getProductionRuleList().getProductionRules()) {
        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) {
            final UnitType ut = units.iterator().next();
            final List<ResourceCollection> current = backups.computeIfAbsent(ut, k -> new ArrayList<>());
            current.add(costPerGroup);
        } else if (totalProduced > 1) {
            costPerGroup.discount((double) 1 / (double) totalProduced);
            for (final UnitType ut : units) {
                final List<ResourceCollection> current = backups.computeIfAbsent(ut, k -> new ArrayList<>());
                current.add(costPerGroup);
            }
        }
    }
    for (final Entry<UnitType, List<ResourceCollection>> entry : backups.entrySet()) {
        final ResourceCollection avgCost = new ResourceCollection(entry.getValue().toArray(new ResourceCollection[0]), data);
        if (entry.getValue().size() > 1) {
            avgCost.discount((double) 1 / (double) entry.getValue().size());
        }
        backupAveraged.put(entry.getKey(), avgCost);
    }
    final Map<PlayerID, Map<UnitType, ResourceCollection>> allPlayersCurrent = getResourceCostsForTuv(data, false);
    allPlayersCurrent.remove(null);
    for (final UnitType ut : data.getUnitTypeList().getAllUnitTypes()) {
        final List<ResourceCollection> costs = new ArrayList<>();
        for (final Map<UnitType, ResourceCollection> entry : allPlayersCurrent.values()) {
            if (entry.get(ut) != null) {
                costs.add(entry.get(ut));
            }
        }
        if (costs.isEmpty()) {
            final ResourceCollection backup = backupAveraged.get(ut);
            if (backup != null) {
                costs.add(backup);
            } else {
                costs.add(defaultResources);
            }
        }
        final ResourceCollection avgCost = new ResourceCollection(costs.toArray(new ResourceCollection[0]), data);
        if (costs.size() > 1) {
            avgCost.discount((double) 1 / (double) costs.size());
        }
        average.put(ut, avgCost);
    }
    return average;
}
Also used : IntegerMap(games.strategy.util.IntegerMap) Unit(games.strategy.engine.data.Unit) Collection(java.util.Collection) Constants(games.strategy.triplea.Constants) Set(java.util.Set) UnitAttachment(games.strategy.triplea.attachments.UnitAttachment) HashMap(java.util.HashMap) NamedAttachable(games.strategy.engine.data.NamedAttachable) Resource(games.strategy.engine.data.Resource) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) LinkedHashMap(java.util.LinkedHashMap) GameData(games.strategy.engine.data.GameData) List(java.util.List) PlayerID(games.strategy.engine.data.PlayerID) ResourceCollection(games.strategy.engine.data.ResourceCollection) ProductionFrontier(games.strategy.engine.data.ProductionFrontier) Matches(games.strategy.triplea.delegate.Matches) Map(java.util.Map) Entry(java.util.Map.Entry) UnitType(games.strategy.engine.data.UnitType) ProductionRule(games.strategy.engine.data.ProductionRule) CollectionUtils(games.strategy.util.CollectionUtils) IntegerMap(games.strategy.util.IntegerMap) PlayerID(games.strategy.engine.data.PlayerID) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) NamedAttachable(games.strategy.engine.data.NamedAttachable) Resource(games.strategy.engine.data.Resource) ArrayList(java.util.ArrayList) ProductionRule(games.strategy.engine.data.ProductionRule) UnitType(games.strategy.engine.data.UnitType) ArrayList(java.util.ArrayList) List(java.util.List) 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 7 with NamedAttachable

use of games.strategy.engine.data.NamedAttachable 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 8 with NamedAttachable

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

the class GameDataExporter method printAttachments.

private void printAttachments(final Tuple<IAttachment, ArrayList<Tuple<String, String>>> attachmentPlusValues) {
    final IAttachment attachment = attachmentPlusValues.getFirst();
    try {
        // TODO: none of the attachment exporter classes have been updated since TripleA version 1.3.2.2
        final String attachmentOptions;
        attachmentOptions = printAttachmentOptionsBasedOnOriginalXml(attachmentPlusValues.getSecond(), attachment);
        final NamedAttachable attachTo = (NamedAttachable) attachment.getAttachedTo();
        // TODO: keep this list updated
        String type = "";
        if (attachTo.getClass().equals(PlayerID.class)) {
            type = "player";
        }
        if (attachTo.getClass().equals(UnitType.class)) {
            type = "unitType";
        }
        if (attachTo.getClass().equals(Territory.class)) {
            type = "territory";
        }
        if (attachTo.getClass().equals(TerritoryEffect.class)) {
            type = "territoryEffect";
        }
        if (attachTo.getClass().equals(Resource.class)) {
            type = "resource";
        }
        if (attachTo.getClass().equals(RelationshipType.class)) {
            type = "relationship";
        }
        if (TechAdvance.class.isAssignableFrom(attachTo.getClass())) {
            type = "technology";
        }
        if (type.isEmpty()) {
            throw new AttachmentExportException("no attachmentType known for " + attachTo.getClass().getCanonicalName());
        }
        if (attachmentOptions.length() > 0) {
            xmlfile.append("        <attachment name=\"").append(attachment.getName()).append("\" attachTo=\"").append(attachTo.getName()).append("\" javaClass=\"").append(attachment.getClass().getCanonicalName()).append("\" type=\"").append(type).append("\">\n");
            xmlfile.append(attachmentOptions);
            xmlfile.append("        </attachment>\n");
        }
    } catch (final Exception e) {
        ClientLogger.logError("An Error occured whilst trying to print the Attachment \"" + attachment.getName() + "\"", e);
    }
}
Also used : NamedAttachable(games.strategy.engine.data.NamedAttachable) IAttachment(games.strategy.engine.data.IAttachment)

Example 9 with NamedAttachable

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

the class PurchaseDelegate method purchase.

@Override
public String purchase(final IntegerMap<ProductionRule> productionRules) {
    final IntegerMap<Resource> costs = getCosts(productionRules);
    final IntegerMap<NamedAttachable> results = getResults(productionRules);
    if (!(canAfford(costs, player))) {
        return NOT_ENOUGH_RESOURCES;
    }
    // check to see if player has too many of any building with a building limit
    for (final NamedAttachable next : results.keySet()) {
        if (!(next instanceof Resource)) {
            final UnitType type = (UnitType) next;
            final int quantity = results.getInt(type);
            final UnitAttachment ua = UnitAttachment.get(type);
            final int maxBuilt = ua.getMaxBuiltPerPlayer();
            if (maxBuilt == 0) {
                return "May not build any of this unit right now: " + type.getName();
            } else if (maxBuilt > 0) {
                // count how many units are yet to be placed or are in the field
                int currentlyBuilt = player.getUnits().countMatches(Matches.unitIsOfType(type));
                final Predicate<Unit> unitTypeOwnedBy = Matches.unitIsOfType(type).and(Matches.unitIsOwnedBy(player));
                final Collection<Territory> allTerrs = getData().getMap().getTerritories();
                for (final Territory t : allTerrs) {
                    currentlyBuilt += t.getUnits().countMatches(unitTypeOwnedBy);
                }
                final int allowedBuild = maxBuilt - currentlyBuilt;
                if (allowedBuild - quantity < 0) {
                    return "May only build " + allowedBuild + " of " + type.getName() + " this turn, may only build " + maxBuilt + " total";
                }
            }
        }
    }
    // remove first, since add logs PUs remaining
    final Collection<Unit> totalUnits = new ArrayList<>();
    final Collection<UnitType> totalUnitTypes = new ArrayList<>();
    final Collection<Resource> totalResources = new ArrayList<>();
    final CompositeChange changes = new CompositeChange();
    // and find all added units
    for (final NamedAttachable next : results.keySet()) {
        if (next instanceof Resource) {
            final Resource resource = (Resource) next;
            final int quantity = results.getInt(resource);
            final Change change = ChangeFactory.changeResourcesChange(player, resource, quantity);
            changes.add(change);
            for (int i = 0; i < quantity; i++) {
                totalResources.add(resource);
            }
        } else {
            final UnitType type = (UnitType) next;
            final int quantity = results.getInt(type);
            final Collection<Unit> units = type.create(quantity, player);
            totalUnits.addAll(units);
            for (int i = 0; i < quantity; i++) {
                totalUnitTypes.add(type);
            }
        }
    }
    final Collection<NamedAttachable> totalAll = new ArrayList<>();
    totalAll.addAll(totalUnitTypes);
    totalAll.addAll(totalResources);
    // add changes for added units
    if (!totalUnits.isEmpty()) {
        final Change change = ChangeFactory.addUnits(player, totalUnits);
        changes.add(change);
    }
    // add changes for spent resources
    final String remaining = removeFromPlayer(costs, changes);
    // add history event
    final String transcriptText;
    if (!totalUnits.isEmpty()) {
        transcriptText = player.getName() + " buy " + MyFormatter.defaultNamedToTextList(totalAll, ", ", true) + "; " + remaining;
    } else {
        transcriptText = player.getName() + " buy nothing; " + remaining;
    }
    bridge.getHistoryWriter().startEvent(transcriptText, totalUnits);
    // commit changes
    bridge.addChange(changes);
    return null;
}
Also used : Territory(games.strategy.engine.data.Territory) NamedAttachable(games.strategy.engine.data.NamedAttachable) Resource(games.strategy.engine.data.Resource) ArrayList(java.util.ArrayList) CompositeChange(games.strategy.engine.data.CompositeChange) Change(games.strategy.engine.data.Change) TripleAUnit(games.strategy.triplea.TripleAUnit) Unit(games.strategy.engine.data.Unit) Predicate(java.util.function.Predicate) UnitAttachment(games.strategy.triplea.attachments.UnitAttachment) UnitType(games.strategy.engine.data.UnitType) Collection(java.util.Collection) CompositeChange(games.strategy.engine.data.CompositeChange)

Example 10 with NamedAttachable

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

the class PlayerUnitsPanel method getUnitTypes.

/**
 * Return all the unit types available for the given player. A unit type is
 * available if the unit can be purchased or if a player has one on the map.
 */
private Collection<UnitType> getUnitTypes(final PlayerID player) {
    Collection<UnitType> unitTypes = new LinkedHashSet<>();
    final ProductionFrontier frontier = player.getProductionFrontier();
    if (frontier != null) {
        for (final ProductionRule rule : frontier) {
            for (final NamedAttachable type : rule.getResults().keySet()) {
                if (type instanceof UnitType) {
                    unitTypes.add((UnitType) type);
                }
            }
        }
    }
    for (final Territory t : data.getMap()) {
        for (final Unit u : t.getUnits()) {
            if (u.getOwner().equals(player)) {
                unitTypes.add(u.getType());
            }
        }
    }
    // Filter out anything like factories, or units that have no combat ability AND cannot be taken casualty
    unitTypes = CollectionUtils.getMatches(unitTypes, Matches.unitTypeCanBeInBattle(!defender, isLand, player, 1, false, false, false));
    return unitTypes;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) Territory(games.strategy.engine.data.Territory) ProductionRule(games.strategy.engine.data.ProductionRule) NamedAttachable(games.strategy.engine.data.NamedAttachable) UnitType(games.strategy.engine.data.UnitType) Unit(games.strategy.engine.data.Unit) ProductionFrontier(games.strategy.engine.data.ProductionFrontier)

Aggregations

NamedAttachable (games.strategy.engine.data.NamedAttachable)14 ProductionRule (games.strategy.engine.data.ProductionRule)11 UnitType (games.strategy.engine.data.UnitType)10 Resource (games.strategy.engine.data.Resource)9 IntegerMap (games.strategy.util.IntegerMap)6 ProductionFrontier (games.strategy.engine.data.ProductionFrontier)5 Unit (games.strategy.engine.data.Unit)5 Territory (games.strategy.engine.data.Territory)4 ArrayList (java.util.ArrayList)4 HashMap (java.util.HashMap)4 HashSet (java.util.HashSet)4 UnitAttachment (games.strategy.triplea.attachments.UnitAttachment)3 LinkedHashMap (java.util.LinkedHashMap)3 CompositeChange (games.strategy.engine.data.CompositeChange)2 GameData (games.strategy.engine.data.GameData)2 PlayerID (games.strategy.engine.data.PlayerID)2 RepairRule (games.strategy.engine.data.RepairRule)2 ResourceCollection (games.strategy.engine.data.ResourceCollection)2 TripleAUnit (games.strategy.triplea.TripleAUnit)2 Collection (java.util.Collection)2