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) {
}
}