package games.strategy.triplea.ai.fastAI; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import games.strategy.engine.data.GameData; import games.strategy.engine.data.PlayerID; import games.strategy.engine.data.Territory; import games.strategy.engine.data.TerritoryEffect; import games.strategy.engine.data.Unit; import games.strategy.triplea.ai.proAI.util.ProBattleUtils; import games.strategy.triplea.ai.proAI.util.ProPurchaseUtils; import games.strategy.triplea.oddsCalculator.ta.AggregateResults; import games.strategy.triplea.oddsCalculator.ta.IOddsCalculator; import games.strategy.triplea.oddsCalculator.ta.OddsCalculatorListener; public class FastOddsEstimator implements IOddsCalculator { private Territory location = null; private Collection<Unit> attackingUnits = new ArrayList<>(); private Collection<Unit> defendingUnits = new ArrayList<>(); @Override public void setGameData(final GameData data) {} @Override public void setCalculateData(final PlayerID attacker, final PlayerID defender, final Territory location, final Collection<Unit> attackingUnits, final Collection<Unit> defendingUnits, final Collection<Unit> bombardingUnits, final Collection<TerritoryEffect> territoryEffects, final int runCount) { this.location = location; this.attackingUnits = attackingUnits; this.defendingUnits = defendingUnits; } @Override public AggregateResults calculate() { final double winPercentage = ProBattleUtils.estimateStrengthDifference(location, new ArrayList<>(attackingUnits), new ArrayList<>(defendingUnits)); final int battleRoundsFought = 3; List<Unit> remainingAttackingUnits = new ArrayList<>(); List<Unit> remainingDefendingUnits = new ArrayList<>(); if (winPercentage > 50) { remainingAttackingUnits.addAll(attackingUnits); Collections.sort(remainingAttackingUnits, ProPurchaseUtils.getCostComparator().reversed()); final int numRemainingUnits = (int) Math.ceil(attackingUnits.size() * (Math.min(100, winPercentage) - 50) / 50); remainingAttackingUnits = remainingAttackingUnits.subList(0, numRemainingUnits); } else { remainingDefendingUnits.addAll(defendingUnits); Collections.sort(remainingDefendingUnits, ProPurchaseUtils.getCostComparator().reversed()); final int numRemainingUnits = (int) Math.ceil(defendingUnits.size() * (50 - Math.max(0, winPercentage)) / 50); remainingDefendingUnits = remainingDefendingUnits.subList(0, numRemainingUnits); } return new AggregateEstimate(battleRoundsFought, winPercentage / 100, remainingAttackingUnits, remainingDefendingUnits); } @Override public AggregateResults setCalculateDataAndCalculate(final PlayerID attacker, final PlayerID defender, final Territory location, final Collection<Unit> attacking, final Collection<Unit> defending, final Collection<Unit> bombarding, final Collection<TerritoryEffect> territoryEffects, final int runCount) { setCalculateData(attacker, defender, location, attacking, defending, bombarding, territoryEffects, runCount); return calculate(); } @Override public int getRunCount() { return 1; } @Override public boolean getIsReady() { return true; } @Override public void setKeepOneAttackingLandUnit(final boolean bool) { } @Override public void setAmphibious(final boolean bool) { } @Override public void setRetreatAfterRound(final int value) { } @Override public void setRetreatAfterXUnitsLeft(final int value) { } @Override public void setRetreatWhenOnlyAirLeft(final boolean value) { } @Override public void setAttackerOrderOfLosses(final String attackerOrderOfLosses) { } @Override public void setDefenderOrderOfLosses(final String defenderOrderOfLosses) { } @Override public void cancel() { } @Override public void shutdown() { } @Override public int getThreadCount() { return 1; } @Override public void addOddsCalculatorListener(final OddsCalculatorListener listener) { } @Override public void removeOddsCalculatorListener(final OddsCalculatorListener listener) { } }