package games.strategy.triplea.util; import java.util.Collection; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; import java.util.TreeSet; import games.strategy.engine.data.Unit; import games.strategy.triplea.TripleAUnit; import games.strategy.triplea.attachments.UnitAttachment; import games.strategy.triplea.delegate.Matches; /** * Seperates a group of units into distinct categories. */ public class UnitSeperator { private UnitSeperator() {} public static Set<UnitCategory> categorize(final Collection<Unit> units) { return categorize(units, null, false, false); } public static Set<UnitCategory> categorize(final Collection<Unit> units, final Map<Unit, Collection<Unit>> dependent, final boolean categorizeMovement, final boolean categorizeTransportCost, final boolean sort) { return categorize(units, dependent, categorizeMovement, categorizeTransportCost, /* ctgzTrnMovement */false, sort); } public static Set<UnitCategory> categorize(final boolean sort, final Collection<Unit> units, final Map<Unit, Collection<Unit>> dependent, final boolean categorizeMovement, final boolean categorizeTransportCost, final boolean categorizeTerritories) { return categorize(units, dependent, categorizeMovement, categorizeTransportCost, /* ctgzTrnMovement */false, sort); } /** * Break the units into discrete categories. * Do this based on unit owner, and optionally dependent units and movement * * @param dependent * - can be null * @param categorizeMovement * - whether to categorize by movement * @param categorizeTrnMovement * - whether to categorize transports by movement * @param sort If true then sort the categories in UnitCategory order; * if false, then leave categories in original order (based on units). * @return a Collection of UnitCategories */ public static Set<UnitCategory> categorize(final Collection<Unit> units, final Map<Unit, Collection<Unit>> dependent, final boolean categorizeMovement, final boolean categorizeTransportCost, final boolean categorizeTrnMovement, final boolean sort) { // somewhat odd, but we map UnitCategory->UnitCategory, // key and value are the same // we do this to take advanatge of .equals() on objects that // are equal in a special way HashMap<UnitCategory, UnitCategory> categories; if (sort) { categories = new HashMap<>(); } else { categories = new LinkedHashMap<>(); } for (final Unit current : units) { int unitMovement = -1; if (categorizeMovement || (categorizeTrnMovement && Matches.UnitIsTransport.match(current))) { unitMovement = TripleAUnit.get(current).getMovementLeft(); } int unitTransportCost = -1; if (categorizeTransportCost) { unitTransportCost = UnitAttachment.get((current).getUnitType()).getTransportCost(); } Collection<Unit> currentDependents = null; if (dependent != null) { currentDependents = dependent.get(current); } final boolean disabled = Matches.UnitIsDisabled.match(current); final UnitCategory entry = new UnitCategory(current, currentDependents, unitMovement, current.getHits(), TripleAUnit.get(current).getUnitDamage(), disabled, unitTransportCost); // we test to see if we have the key using equals, then since // key maps to key, we retrieve it to add the unit to the correct // category if (categories.containsKey(entry)) { final UnitCategory stored = categories.get(entry); stored.addUnit(current); } else { categories.put(entry, entry); } } if (sort) { return new TreeSet<>(categories.keySet()); } else { return new LinkedHashSet<>(categories.keySet()); } } /** * Legacy interface. * Break the units into discrete categories. * Do this based on unit owner, and optionally dependent units and movement * * @param dependent * - can be null * @param categorizeMovement * - whether to categorize by movement * @return a Collection of UnitCategories */ public static Set<UnitCategory> categorize(final Collection<Unit> units, final Map<Unit, Collection<Unit>> dependent, final boolean categorizeMovement, final boolean categorizeTransportCost) { // sort by default return categorize(units, dependent, categorizeMovement, categorizeTransportCost, true); } public static Set<UnitCategory> categorize(final Map<Unit, Collection<Unit>> dependent, final Collection<Unit> units, final boolean categorizeMovement, final boolean categorizeTransportCost, final boolean categorizeTerritories) { // sort by default return categorize(true, units, dependent, categorizeMovement, categorizeTransportCost, categorizeTerritories); } }