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