use of games.strategy.triplea.delegate.IBattle in project triplea by triplea-game.
the class ProAi method scrambleUnitsQuery.
@Override
public HashMap<Territory, Collection<Unit>> scrambleUnitsQuery(final Territory scrambleTo, final Map<Territory, Tuple<Collection<Unit>, Collection<Unit>>> possibleScramblers) {
initializeData();
// Get battle data
final GameData data = getGameData();
final PlayerID player = getPlayerId();
final BattleDelegate delegate = DelegateFinder.battleDelegate(data);
final IBattle battle = delegate.getBattleTracker().getPendingBattle(scrambleTo, false, BattleType.NORMAL);
// If battle is null then don't scramble
if (battle == null) {
return null;
}
final List<Unit> attackers = (List<Unit>) battle.getAttackingUnits();
final List<Unit> defenders = (List<Unit>) battle.getDefendingUnits();
ProLogger.info(player.getName() + " checking scramble to " + scrambleTo + ", attackers=" + attackers.size() + ", defenders=" + defenders.size() + ", possibleScramblers=" + possibleScramblers);
calc.setData(getGameData());
return scrambleAi.scrambleUnitsQuery(scrambleTo, possibleScramblers);
}
use of games.strategy.triplea.delegate.IBattle in project triplea by triplea-game.
the class ProRetreatAi method retreatQuery.
Territory retreatQuery(final GUID battleId, final Territory battleTerritory, final Collection<Territory> possibleTerritories) {
// Get battle data
final GameData data = ProData.getData();
final PlayerID player = ProData.getPlayer();
final BattleDelegate delegate = DelegateFinder.battleDelegate(data);
final IBattle battle = delegate.getBattleTracker().getPendingBattle(battleId);
// Get units and determine if attacker
final boolean isAttacker = player.equals(battle.getAttacker());
final List<Unit> attackers = (List<Unit>) battle.getAttackingUnits();
final List<Unit> defenders = (List<Unit>) battle.getDefendingUnits();
// Calculate battle results
final ProBattleResult result = calc.calculateBattleResults(battleTerritory, attackers, defenders, new HashSet<>());
// Determine if it has a factory
int isFactory = 0;
if (ProMatches.territoryHasInfraFactoryAndIsLand().test(battleTerritory)) {
isFactory = 1;
}
// Determine production value and if it is a capital
int production = 0;
int isCapital = 0;
final TerritoryAttachment ta = TerritoryAttachment.get(battleTerritory);
if (ta != null) {
production = ta.getProduction();
if (ta.isCapital()) {
isCapital = 1;
}
}
// Calculate current attack value
double territoryValue = 0;
if (result.isHasLandUnitRemaining() || attackers.stream().noneMatch(Matches.unitIsAir())) {
territoryValue = result.getWinPercentage() / 100 * (2 * production * (1 + isFactory) * (1 + isCapital));
}
double battleValue = result.getTuvSwing() + territoryValue;
if (!isAttacker) {
battleValue = -battleValue;
}
// Decide if we should retreat
if (battleValue < 0) {
// Retreat to capital if available otherwise the territory with highest defense strength
Territory retreatTerritory = null;
double maxStrength = Double.NEGATIVE_INFINITY;
final Territory myCapital = TerritoryAttachment.getFirstOwnedCapitalOrFirstUnownedCapital(player, data);
for (final Territory t : possibleTerritories) {
if (t.equals(myCapital)) {
retreatTerritory = t;
break;
}
final double strength = ProBattleUtils.estimateStrength(t, t.getUnits().getMatches(Matches.isUnitAllied(player, data)), new ArrayList<>(), false);
if (strength > maxStrength) {
retreatTerritory = t;
maxStrength = strength;
}
}
ProLogger.debug(player.getName() + " retreating from territory " + battleTerritory + " to " + retreatTerritory + " because AttackValue=" + battleValue + ", TUVSwing=" + result.getTuvSwing() + ", possibleTerritories=" + possibleTerritories.size());
return retreatTerritory;
}
ProLogger.debug(player.getName() + " not retreating from territory " + battleTerritory + " with AttackValue=" + battleValue + ", TUVSwing=" + result.getTuvSwing());
return null;
}
use of games.strategy.triplea.delegate.IBattle in project triplea by triplea-game.
the class ProScrambleAi method scrambleUnitsQuery.
HashMap<Territory, Collection<Unit>> scrambleUnitsQuery(final Territory scrambleTo, final Map<Territory, Tuple<Collection<Unit>, Collection<Unit>>> possibleScramblers) {
// Get battle data
final GameData data = ProData.getData();
final PlayerID player = ProData.getPlayer();
final BattleDelegate delegate = DelegateFinder.battleDelegate(data);
final IBattle battle = delegate.getBattleTracker().getPendingBattle(scrambleTo, false, BattleType.NORMAL);
// Check if defense already wins
final List<Unit> attackers = (List<Unit>) battle.getAttackingUnits();
final List<Unit> defenders = (List<Unit>) battle.getDefendingUnits();
final Set<Unit> bombardingUnits = new HashSet<>(battle.getBombardingUnits());
final ProBattleResult minResult = calc.calculateBattleResults(scrambleTo, attackers, defenders, bombardingUnits);
ProLogger.debug(scrambleTo + ", minTUVSwing=" + minResult.getTuvSwing() + ", minWin%=" + minResult.getWinPercentage());
if (minResult.getTuvSwing() <= 0 && minResult.getWinPercentage() < (100 - ProData.minWinPercentage)) {
return null;
}
// Check if max defense is worse
final Set<Unit> allScramblers = new HashSet<>();
final Map<Territory, List<Unit>> possibleMaxScramblerMap = new HashMap<>();
for (final Territory t : possibleScramblers.keySet()) {
final int maxCanScramble = BattleDelegate.getMaxScrambleCount(possibleScramblers.get(t).getFirst());
List<Unit> canScrambleAir = new ArrayList<>(possibleScramblers.get(t).getSecond());
if (maxCanScramble < canScrambleAir.size()) {
canScrambleAir.sort(Comparator.comparingDouble(o -> ProBattleUtils.estimateStrength(scrambleTo, Collections.singletonList(o), new ArrayList<>(), false)));
canScrambleAir = canScrambleAir.subList(0, maxCanScramble);
}
allScramblers.addAll(canScrambleAir);
possibleMaxScramblerMap.put(t, canScrambleAir);
}
defenders.addAll(allScramblers);
final ProBattleResult maxResult = calc.calculateBattleResults(scrambleTo, attackers, defenders, bombardingUnits);
ProLogger.debug(scrambleTo + ", maxTUVSwing=" + maxResult.getTuvSwing() + ", maxWin%=" + maxResult.getWinPercentage());
if (maxResult.getTuvSwing() >= minResult.getTuvSwing()) {
return null;
}
// Loop through all units and determine attack options
final Map<Unit, Set<Territory>> unitDefendOptions = new HashMap<>();
for (final Territory t : possibleMaxScramblerMap.keySet()) {
final Set<Territory> possibleTerritories = data.getMap().getNeighbors(t, ProMatches.territoryCanMoveSeaUnits(player, data, true));
possibleTerritories.add(t);
final Set<Territory> battleTerritories = new HashSet<>();
for (final Territory possibleTerritory : possibleTerritories) {
final IBattle possibleBattle = delegate.getBattleTracker().getPendingBattle(possibleTerritory, false, BattleType.NORMAL);
if (possibleBattle != null) {
battleTerritories.add(possibleTerritory);
}
}
for (final Unit u : possibleMaxScramblerMap.get(t)) {
unitDefendOptions.put(u, battleTerritories);
}
}
// Sort units by number of defend options and cost
final Map<Unit, Set<Territory>> sortedUnitDefendOptions = ProSortMoveOptionsUtils.sortUnitMoveOptions(unitDefendOptions);
// Add one scramble unit at a time and check if final result is better than min result
final List<Unit> unitsToScramble = new ArrayList<>();
ProBattleResult result = minResult;
for (final Unit u : sortedUnitDefendOptions.keySet()) {
unitsToScramble.add(u);
final List<Unit> currentDefenders = (List<Unit>) battle.getDefendingUnits();
currentDefenders.addAll(unitsToScramble);
result = calc.calculateBattleResults(scrambleTo, attackers, currentDefenders, bombardingUnits);
ProLogger.debug(scrambleTo + ", TUVSwing=" + result.getTuvSwing() + ", Win%=" + result.getWinPercentage() + ", addedUnit=" + u);
if (result.getTuvSwing() <= 0 && result.getWinPercentage() < (100 - ProData.minWinPercentage)) {
break;
}
}
if (result.getTuvSwing() >= minResult.getTuvSwing()) {
return null;
}
// Return units to scramble
final HashMap<Territory, Collection<Unit>> scrambleMap = new HashMap<>();
for (final Territory t : possibleScramblers.keySet()) {
for (final Unit u : possibleScramblers.get(t).getSecond()) {
if (unitsToScramble.contains(u)) {
if (scrambleMap.containsKey(t)) {
scrambleMap.get(t).add(u);
} else {
final Collection<Unit> units = new ArrayList<>();
units.add(u);
scrambleMap.put(t, units);
}
}
}
}
return scrambleMap;
}
Aggregations