package games.strategy.triplea.delegate; import java.util.Collection; import java.util.Comparator; import java.util.HashSet; import games.strategy.engine.data.GameData; import games.strategy.engine.data.TerritoryEffect; import games.strategy.engine.data.Unit; import games.strategy.engine.data.UnitType; import games.strategy.triplea.attachments.UnitAttachment; import games.strategy.util.IntegerMap; public class UnitBattleComparator implements Comparator<Unit> { private final boolean m_defending; private final IntegerMap<UnitType> m_costs; private final GameData m_data; private final boolean m_bonus; private final boolean m_ignorePrimaryPower; private final Collection<TerritoryEffect> m_territoryEffects; private final Collection<UnitType> m_multiHitpointCanRepair = new HashSet<>(); public UnitBattleComparator(final boolean defending, final IntegerMap<UnitType> costs, final Collection<TerritoryEffect> territoryEffects, final GameData data, final boolean bonus, final boolean ignorePrimaryPower) { m_defending = defending; m_costs = costs; m_data = data; m_bonus = bonus; m_ignorePrimaryPower = ignorePrimaryPower; m_territoryEffects = territoryEffects; if (games.strategy.triplea.Properties.getBattleshipsRepairAtEndOfRound(data) || games.strategy.triplea.Properties.getBattleshipsRepairAtBeginningOfRound(data)) { for (final UnitType ut : data.getUnitTypeList()) { if (Matches.UnitTypeHasMoreThanOneHitPointTotal.match(ut)) { m_multiHitpointCanRepair.add(ut); } } // TODO: check if there are units in the game that can repair this unit } } @Override public int compare(final Unit u1, final Unit u2) { if (u1.equals(u2)) { return 0; } final boolean transporting1 = Matches.transportIsTransporting().match(u1); final boolean transporting2 = Matches.transportIsTransporting().match(u2); final UnitAttachment ua1 = UnitAttachment.get(u1.getType()); final UnitAttachment ua2 = UnitAttachment.get(u2.getType()); if (ua1 == ua2 && u1.getOwner().equals(u2.getOwner())) { if (transporting1 && !transporting2) { return 1; } if (!transporting1 && transporting2) { return -1; } return 0; } final boolean airOrCarrierOrTransport1 = Matches.UnitIsAir.match(u1) || Matches.UnitIsCarrier.match(u1) || (!transporting1 && Matches.UnitIsTransport.match(u1)); final boolean airOrCarrierOrTransport2 = Matches.UnitIsAir.match(u2) || Matches.UnitIsCarrier.match(u2) || (!transporting2 && Matches.UnitIsTransport.match(u2)); final boolean subDestroyer1 = Matches.UnitIsSub.match(u1) || Matches.UnitIsDestroyer.match(u1); final boolean subDestroyer2 = Matches.UnitIsSub.match(u2) || Matches.UnitIsDestroyer.match(u2); final boolean multiHpCanRepair1 = m_multiHitpointCanRepair.contains(u1.getType()); final boolean multiHpCanRepair2 = m_multiHitpointCanRepair.contains(u2.getType()); if (!m_ignorePrimaryPower) { int power1 = 8 * BattleCalculator.getUnitPowerForSorting(u1, m_defending, m_data, m_territoryEffects); int power2 = 8 * BattleCalculator.getUnitPowerForSorting(u2, m_defending, m_data, m_territoryEffects); if (m_bonus) { if (subDestroyer1 && !subDestroyer2) { power1 += 4; } else if (!subDestroyer1 && subDestroyer2) { power2 += 4; } if (multiHpCanRepair1 && !multiHpCanRepair2) { power1++; } else if (!multiHpCanRepair1 && multiHpCanRepair2) { power2++; } if (transporting1 && !transporting2) { power1++; } else if (!transporting1 && transporting2) { power2++; } if (airOrCarrierOrTransport1 && !airOrCarrierOrTransport2) { power1++; } else if (!airOrCarrierOrTransport1 && airOrCarrierOrTransport2) { power2++; } } if (power1 != power2) { return power1 - power2; } } { final int cost1 = m_costs.getInt(u1.getType()); final int cost2 = m_costs.getInt(u2.getType()); if (cost1 != cost2) { return cost1 - cost2; } } { int power1reverse = 8 * BattleCalculator.getUnitPowerForSorting(u1, !m_defending, m_data, m_territoryEffects); int power2reverse = 8 * BattleCalculator.getUnitPowerForSorting(u2, !m_defending, m_data, m_territoryEffects); if (m_bonus) { if (subDestroyer1 && !subDestroyer2) { power1reverse += 4; } else if (!subDestroyer1 && subDestroyer2) { power2reverse += 4; } if (multiHpCanRepair1 && !multiHpCanRepair2) { power1reverse++; } else if (!multiHpCanRepair1 && multiHpCanRepair2) { power2reverse++; } if (transporting1 && !transporting2) { power1reverse++; } else if (!transporting1 && transporting2) { power2reverse++; } if (airOrCarrierOrTransport1 && !airOrCarrierOrTransport2) { power1reverse++; } else if (!airOrCarrierOrTransport1 && airOrCarrierOrTransport2) { power2reverse++; } } if (power1reverse != power2reverse) { return power1reverse - power2reverse; } } if (subDestroyer1 && !subDestroyer2) { return 1; } else if (!subDestroyer1 && subDestroyer2) { return -1; } if (multiHpCanRepair1 && !multiHpCanRepair2) { return 1; } else if (!multiHpCanRepair1 && multiHpCanRepair2) { return -1; } if (transporting1 && !transporting2) { return 1; } else if (!transporting1 && transporting2) { return -1; } if (airOrCarrierOrTransport1 && !airOrCarrierOrTransport2) { return 1; } else if (!airOrCarrierOrTransport1 && airOrCarrierOrTransport2) { return -1; } return ua1.getMovement(u1.getOwner()) - ua2.getMovement(u2.getOwner()); } }