use of games.strategy.triplea.delegate.BattleDelegate in project triplea by triplea-game.
the class ProAi method retreatQuery.
@Override
public Territory retreatQuery(final GUID battleId, final boolean submerge, final Territory battleTerritory, final Collection<Territory> possibleTerritories, final String message) {
initializeData();
// Get battle data
final GameData data = getGameData();
final PlayerID player = getPlayerId();
final BattleDelegate delegate = DelegateFinder.battleDelegate(data);
final IBattle battle = delegate.getBattleTracker().getPendingBattle(battleId);
// If battle is null or amphibious then don't retreat
if (battle == null || battleTerritory == null || battle.isAmphibious()) {
return null;
}
// If attacker with more unit strength or strafing and isn't land battle with only air left then don't retreat
final boolean isAttacker = player.equals(battle.getAttacker());
final List<Unit> attackers = (List<Unit>) battle.getAttackingUnits();
final List<Unit> defenders = (List<Unit>) battle.getDefendingUnits();
final double strengthDifference = ProBattleUtils.estimateStrengthDifference(battleTerritory, attackers, defenders);
final boolean isStrafing = isAttacker && storedStrafingTerritories.contains(battleTerritory);
ProLogger.info(player.getName() + " checking retreat from territory " + battleTerritory + ", attackers=" + attackers.size() + ", defenders=" + defenders.size() + ", submerge=" + submerge + ", attacker=" + isAttacker + ", isStrafing=" + isStrafing);
if ((isStrafing || (isAttacker && strengthDifference > 50)) && (battleTerritory.isWater() || attackers.stream().anyMatch(Matches.unitIsLand()))) {
return null;
}
calc.setData(getGameData());
return retreatAi.retreatQuery(battleId, battleTerritory, possibleTerritories);
}
use of games.strategy.triplea.delegate.BattleDelegate in project triplea by triplea-game.
the class ProAi method selectCasualties.
@Override
public CasualtyDetails selectCasualties(final Collection<Unit> selectFrom, final Map<Unit, Collection<Unit>> dependents, final int count, final String message, final DiceRoll dice, final PlayerID hit, final Collection<Unit> friendlyUnits, final PlayerID enemyPlayer, final Collection<Unit> enemyUnits, final boolean amphibious, final Collection<Unit> amphibiousLandAttackers, final CasualtyList defaultCasualties, final GUID battleId, final Territory battlesite, final boolean allowMultipleHitsPerUnit) {
initializeData();
if (defaultCasualties.size() != count) {
throw new IllegalStateException("Select Casualties showing different numbers for number of hits to take vs total " + "size of default casualty selections");
}
if (defaultCasualties.getKilled().size() <= 0) {
return new CasualtyDetails(defaultCasualties, false);
}
// Consider unit cost
final CasualtyDetails myCasualties = new CasualtyDetails(false);
myCasualties.addToDamaged(defaultCasualties.getDamaged());
final List<Unit> selectFromSorted = new ArrayList<>(selectFrom);
if (enemyUnits.isEmpty()) {
selectFromSorted.sort(ProPurchaseUtils.getCostComparator());
} else {
// Get battle data
final GameData data = getGameData();
final PlayerID player = getPlayerId();
final BattleDelegate delegate = DelegateFinder.battleDelegate(data);
final IBattle battle = delegate.getBattleTracker().getPendingBattle(battleId);
// If defender and could lose battle then don't consider unit cost as just trying to survive
boolean needToCheck = true;
final boolean isAttacker = player.equals(battle.getAttacker());
if (!isAttacker) {
final List<Unit> attackers = (List<Unit>) battle.getAttackingUnits();
final List<Unit> defenders = (List<Unit>) battle.getDefendingUnits();
defenders.removeAll(defaultCasualties.getKilled());
final double strengthDifference = ProBattleUtils.estimateStrengthDifference(battlesite, attackers, defenders);
int minStrengthDifference = 60;
if (!Properties.getLowLuck(data)) {
minStrengthDifference = 55;
}
if (strengthDifference > minStrengthDifference) {
needToCheck = false;
}
}
// Use bubble sort to save expensive units
while (needToCheck) {
needToCheck = false;
for (int i = 0; i < selectFromSorted.size() - 1; i++) {
final Unit unit1 = selectFromSorted.get(i);
final Unit unit2 = selectFromSorted.get(i + 1);
final double unitCost1 = ProPurchaseUtils.getCost(unit1);
final double unitCost2 = ProPurchaseUtils.getCost(unit2);
if (unitCost1 > 1.5 * unitCost2) {
selectFromSorted.set(i, unit2);
selectFromSorted.set(i + 1, unit1);
needToCheck = true;
}
}
}
}
// Interleave carriers and planes
final List<Unit> interleavedTargetList = new ArrayList<>(ProTransportUtils.interleaveUnitsCarriersAndPlanes(selectFromSorted, 0));
for (int i = 0; i < defaultCasualties.getKilled().size(); ++i) {
myCasualties.addToKilled(interleavedTargetList.get(i));
}
if (count != myCasualties.size()) {
throw new IllegalStateException("AI chose wrong number of casualties");
}
return myCasualties;
}
use of games.strategy.triplea.delegate.BattleDelegate in project triplea by triplea-game.
the class ProAi method selectAttackSubs.
@Override
public boolean selectAttackSubs(final Territory unitTerritory) {
initializeData();
// Get battle data
final GameData data = getGameData();
final PlayerID player = getPlayerId();
final BattleDelegate delegate = DelegateFinder.battleDelegate(data);
final IBattle battle = delegate.getBattleTracker().getPendingBattle(unitTerritory, false, BattleType.NORMAL);
// If battle is null then don't attack
if (battle == null) {
return false;
}
final List<Unit> attackers = (List<Unit>) battle.getAttackingUnits();
final List<Unit> defenders = (List<Unit>) battle.getDefendingUnits();
ProLogger.info(player.getName() + " checking sub attack in " + unitTerritory + ", attackers=" + attackers + ", defenders=" + defenders);
calc.setData(getGameData());
// Calculate battle results
final ProBattleResult result = calc.calculateBattleResults(unitTerritory, attackers, defenders, new HashSet<>());
ProLogger.debug(player.getName() + " sub attack TUVSwing=" + result.getTuvSwing());
return result.getTuvSwing() > 0;
}
use of games.strategy.triplea.delegate.BattleDelegate in project triplea by triplea-game.
the class ProSimulateTurnUtils method simulateBattles.
public static void simulateBattles(final GameData data, final PlayerID player, final IDelegateBridge delegateBridge, final ProOddsCalculator calc) {
ProLogger.info("Starting battle simulation phase");
final BattleDelegate battleDelegate = DelegateFinder.battleDelegate(data);
final Map<BattleType, Collection<Territory>> battleTerritories = battleDelegate.getBattles().getBattles();
for (final Entry<BattleType, Collection<Territory>> entry : battleTerritories.entrySet()) {
for (final Territory t : entry.getValue()) {
final IBattle battle = battleDelegate.getBattleTracker().getPendingBattle(t, entry.getKey().isBombingRun(), entry.getKey());
final List<Unit> attackers = (List<Unit>) battle.getAttackingUnits();
attackers.retainAll(t.getUnits().getUnits());
final List<Unit> defenders = (List<Unit>) battle.getDefendingUnits();
defenders.retainAll(t.getUnits().getUnits());
final Set<Unit> bombardingUnits = new HashSet<>(battle.getBombardingUnits());
ProLogger.debug("---" + t);
ProLogger.debug("attackers=" + attackers);
ProLogger.debug("defenders=" + defenders);
ProLogger.debug("bombardingUnits=" + bombardingUnits);
final ProBattleResult result = calc.callBattleCalculator(t, attackers, defenders, bombardingUnits);
final List<Unit> remainingUnits = result.getAverageAttackersRemaining();
ProLogger.debug("remainingUnits=" + remainingUnits);
// Make updates to data
final List<Unit> attackersToRemove = new ArrayList<>(attackers);
attackersToRemove.removeAll(remainingUnits);
final List<Unit> defendersToRemove = CollectionUtils.getMatches(defenders, Matches.unitIsInfrastructure().negate());
final List<Unit> infrastructureToChangeOwner = CollectionUtils.getMatches(defenders, Matches.unitIsInfrastructure());
ProLogger.debug("attackersToRemove=" + attackersToRemove);
ProLogger.debug("defendersToRemove=" + defendersToRemove);
ProLogger.debug("infrastructureToChangeOwner=" + infrastructureToChangeOwner);
final Change attackerskilledChange = ChangeFactory.removeUnits(t, attackersToRemove);
delegateBridge.addChange(attackerskilledChange);
final Change defenderskilledChange = ChangeFactory.removeUnits(t, defendersToRemove);
delegateBridge.addChange(defenderskilledChange);
BattleTracker.captureOrDestroyUnits(t, player, player, delegateBridge, null);
if (!checkIfCapturedTerritoryIsAlliedCapital(t, data, player, delegateBridge)) {
delegateBridge.addChange(ChangeFactory.changeOwner(t, player));
}
battleDelegate.getBattleTracker().getConquered().add(t);
battleDelegate.getBattleTracker().removeBattle(battle);
final Territory updatedTerritory = data.getMap().getTerritory(t.getName());
ProLogger.debug("after changes owner=" + updatedTerritory.getOwner() + ", units=" + updatedTerritory.getUnits().getUnits());
}
}
}
use of games.strategy.triplea.delegate.BattleDelegate in project triplea by triplea-game.
the class WeakAi method movePlanesHomeNonCom.
private void movePlanesHomeNonCom(final List<Collection<Unit>> moveUnits, final List<Route> moveRoutes, final PlayerID player, final GameData data) {
// the preferred way to get the delegate
final IMoveDelegate delegateRemote = (IMoveDelegate) getPlayerBridge().getRemoteDelegate();
// this works because we are on the server
final BattleDelegate delegate = DelegateFinder.battleDelegate(data);
final Predicate<Territory> canLand = Matches.isTerritoryAllied(player, data).and(o -> !delegate.getBattleTracker().wasConquered(o));
final Predicate<Territory> routeCondition = Matches.territoryHasEnemyAaForCombatOnly(player, data).negate().and(Matches.territoryIsImpassable().negate());
for (final Territory t : delegateRemote.getTerritoriesWhereAirCantLand()) {
final Route noAaRoute = Utils.findNearest(t, canLand, routeCondition, data);
final Route aaRoute = Utils.findNearest(t, canLand, Matches.territoryIsImpassable().negate(), data);
final Collection<Unit> airToLand = t.getUnits().getMatches(Matches.unitIsAir().and(Matches.unitIsOwnedBy(player)));
// dont bother to see if all the air units have enough movement points
// to move without aa guns firing
// simply move first over no aa, then with aa
// one (but hopefully not both) will be rejected
moveUnits.add(airToLand);
moveRoutes.add(noAaRoute);
moveUnits.add(airToLand);
moveRoutes.add(aaRoute);
}
}
Aggregations