use of games.strategy.triplea.ai.pro.data.ProTerritory in project triplea by triplea-game.
the class ProMoveUtils method calculateMoveRoutes.
public static void calculateMoveRoutes(final PlayerID player, final List<Collection<Unit>> moveUnits, final List<Route> moveRoutes, final Map<Territory, ProTerritory> attackMap, final boolean isCombatMove) {
final GameData data = ProData.getData();
// Find all amphib units
final Set<Unit> amphibUnits = attackMap.values().stream().map(ProTerritory::getAmphibAttackMap).map(Map::entrySet).flatMap(Collection::stream).flatMap(e -> Stream.concat(Stream.of(e.getKey()), e.getValue().stream())).collect(Collectors.toSet());
// Loop through all territories to attack
for (final Territory t : attackMap.keySet()) {
// Loop through each unit that is attacking the current territory
for (final Unit u : attackMap.get(t).getUnits()) {
// Skip amphib units
if (amphibUnits.contains(u)) {
continue;
}
// Skip if unit is already in move to territory
final Territory startTerritory = ProData.unitTerritoryMap.get(u);
if (startTerritory == null || startTerritory.equals(t)) {
continue;
}
// Add unit to move list
final List<Unit> unitList = new ArrayList<>();
unitList.add(u);
moveUnits.add(unitList);
// If carrier has dependent allied fighters then move them too
if (Matches.unitIsCarrier().test(u)) {
final Map<Unit, Collection<Unit>> carrierMustMoveWith = MoveValidator.carrierMustMoveWith(startTerritory.getUnits().getUnits(), startTerritory, data, player);
if (carrierMustMoveWith.containsKey(u)) {
unitList.addAll(carrierMustMoveWith.get(u));
}
}
// Determine route and add to move list
Route route = null;
if (unitList.stream().anyMatch(Matches.unitIsSea())) {
// Sea unit (including carriers with planes)
route = data.getMap().getRoute_IgnoreEnd(startTerritory, t, ProMatches.territoryCanMoveSeaUnitsThrough(player, data, isCombatMove));
} else if (!unitList.isEmpty() && unitList.stream().allMatch(Matches.unitIsLand())) {
// Land unit
route = data.getMap().getRoute_IgnoreEnd(startTerritory, t, ProMatches.territoryCanMoveLandUnitsThrough(player, data, u, startTerritory, isCombatMove, new ArrayList<>()));
} else if (!unitList.isEmpty() && unitList.stream().allMatch(Matches.unitIsAir())) {
// Air unit
route = data.getMap().getRoute_IgnoreEnd(startTerritory, t, ProMatches.territoryCanMoveAirUnitsAndNoAa(player, data, isCombatMove));
}
if (route == null) {
ProLogger.warn(data.getSequence().getRound() + "-" + data.getSequence().getStep().getName() + ": route is null " + startTerritory + " to " + t + ", units=" + unitList);
}
moveRoutes.add(route);
}
}
}
use of games.strategy.triplea.ai.pro.data.ProTerritory in project triplea by triplea-game.
the class ProMoveUtils method calculateBombingRoutes.
public static void calculateBombingRoutes(final PlayerID player, final List<Collection<Unit>> moveUnits, final List<Route> moveRoutes, final Map<Territory, ProTerritory> attackMap) {
final GameData data = ProData.getData();
// Loop through all territories to attack
for (final Territory t : attackMap.keySet()) {
// Loop through each unit that is attacking the current territory
for (final Unit u : attackMap.get(t).getBombers()) {
// Skip if unit is already in move to territory
final Territory startTerritory = ProData.unitTerritoryMap.get(u);
if (startTerritory == null || startTerritory.equals(t)) {
continue;
}
// Add unit to move list
final List<Unit> unitList = new ArrayList<>();
unitList.add(u);
moveUnits.add(unitList);
// Determine route and add to move list
Route route = null;
if (!unitList.isEmpty() && unitList.stream().allMatch(Matches.unitIsAir())) {
route = data.getMap().getRoute_IgnoreEnd(startTerritory, t, ProMatches.territoryCanMoveAirUnitsAndNoAa(player, data, true));
}
moveRoutes.add(route);
}
}
}
use of games.strategy.triplea.ai.pro.data.ProTerritory in project triplea by triplea-game.
the class ProSortMoveOptionsUtils method sortUnitNeededOptions.
public static Map<Unit, Set<Territory>> sortUnitNeededOptions(final PlayerID player, final Map<Unit, Set<Territory>> unitAttackOptions, final Map<Territory, ProTerritory> attackMap, final ProOddsCalculator calc) {
final GameData data = ProData.getData();
final List<Map.Entry<Unit, Set<Territory>>> list = new ArrayList<>(unitAttackOptions.entrySet());
list.sort((o1, o2) -> {
// Find number of territories that still need units
int numOptions1 = 0;
for (final Territory t : o1.getValue()) {
final ProTerritory patd = attackMap.get(t);
if (patd.getBattleResult() == null) {
patd.setBattleResult(calc.estimateAttackBattleResults(t, patd.getUnits(), patd.getMaxEnemyDefenders(player, data), patd.getBombardTerritoryMap().keySet()));
}
if (!patd.isCurrentlyWins()) {
numOptions1++;
}
}
int numOptions2 = 0;
for (final Territory t : o2.getValue()) {
final ProTerritory patd = attackMap.get(t);
if (patd.getBattleResult() == null) {
patd.setBattleResult(calc.estimateAttackBattleResults(t, patd.getUnits(), patd.getMaxEnemyDefenders(player, data), patd.getBombardTerritoryMap().keySet()));
}
if (!patd.isCurrentlyWins()) {
numOptions2++;
}
}
// Sort by number of move options then cost of unit then unit type
if (numOptions1 != numOptions2) {
return (numOptions1 - numOptions2);
}
if (ProData.unitValueMap.getInt(o1.getKey().getType()) != ProData.unitValueMap.getInt(o2.getKey().getType())) {
return (ProData.unitValueMap.getInt(o1.getKey().getType()) - ProData.unitValueMap.getInt(o2.getKey().getType()));
}
return o1.getKey().getType().getName().compareTo(o2.getKey().getType().getName());
});
final Map<Unit, Set<Territory>> sortedUnitAttackOptions = new LinkedHashMap<>();
for (final Map.Entry<Unit, Set<Territory>> entry : list) {
sortedUnitAttackOptions.put(entry.getKey(), entry.getValue());
}
return sortedUnitAttackOptions;
}
use of games.strategy.triplea.ai.pro.data.ProTerritory in project triplea by triplea-game.
the class ProSortMoveOptionsUtils method sortUnitNeededOptionsThenAttack.
public static Map<Unit, Set<Territory>> sortUnitNeededOptionsThenAttack(final PlayerID player, final Map<Unit, Set<Territory>> unitAttackOptions, final Map<Territory, ProTerritory> attackMap, final Map<Unit, Territory> unitTerritoryMap, final ProOddsCalculator calc) {
final GameData data = ProData.getData();
final List<Map.Entry<Unit, Set<Territory>>> list = new ArrayList<>(unitAttackOptions.entrySet());
list.sort((o1, o2) -> {
// Sort by number of territories that still need units
int numOptions1 = 0;
for (final Territory t : o1.getValue()) {
final ProTerritory patd = attackMap.get(t);
if (patd.getBattleResult() == null) {
patd.setBattleResult(calc.estimateAttackBattleResults(t, patd.getUnits(), patd.getMaxEnemyDefenders(player, data), patd.getBombardTerritoryMap().keySet()));
}
if (!patd.isCurrentlyWins()) {
numOptions1++;
}
}
int numOptions2 = 0;
for (final Territory t : o2.getValue()) {
final ProTerritory patd = attackMap.get(t);
if (patd.getBattleResult() == null) {
patd.setBattleResult(calc.estimateAttackBattleResults(t, patd.getUnits(), patd.getMaxEnemyDefenders(player, data), patd.getBombardTerritoryMap().keySet()));
}
if (!patd.isCurrentlyWins()) {
numOptions2++;
}
}
if (numOptions1 != numOptions2) {
return (numOptions1 - numOptions2);
}
if (numOptions1 == 0) {
return 0;
}
// Sort by attack efficiency
int minPower1 = Integer.MAX_VALUE;
for (final Territory t : o1.getValue()) {
if (!attackMap.get(t).isCurrentlyWins()) {
final List<Unit> defendingUnits = t.getUnits().getMatches(Matches.enemyUnit(player, data));
final List<Unit> sortedUnitsList = new ArrayList<>(attackMap.get(t).getUnits());
sortedUnitsList.sort(new UnitBattleComparator(false, ProData.unitValueMap, TerritoryEffectHelper.getEffects(t), data, false, false));
Collections.reverse(sortedUnitsList);
final int powerWithout = DiceRoll.getTotalPower(DiceRoll.getUnitPowerAndRollsForNormalBattles(sortedUnitsList, defendingUnits, false, false, data, t, TerritoryEffectHelper.getEffects(t), false, null), data);
sortedUnitsList.add(o1.getKey());
sortedUnitsList.sort(new UnitBattleComparator(false, ProData.unitValueMap, TerritoryEffectHelper.getEffects(t), data, false, false));
Collections.reverse(sortedUnitsList);
final int powerWith = DiceRoll.getTotalPower(DiceRoll.getUnitPowerAndRollsForNormalBattles(sortedUnitsList, defendingUnits, false, false, data, t, TerritoryEffectHelper.getEffects(t), false, null), data);
final int power = powerWith - powerWithout;
if (power < minPower1) {
minPower1 = power;
}
}
}
final UnitAttachment ua1 = UnitAttachment.get(o1.getKey().getType());
if (ua1.getIsAir()) {
minPower1 *= 10;
}
final double attackEfficiency1 = (double) minPower1 / ProData.unitValueMap.getInt(o1.getKey().getType());
int minPower2 = Integer.MAX_VALUE;
for (final Territory t : o2.getValue()) {
if (!attackMap.get(t).isCurrentlyWins()) {
final List<Unit> defendingUnits = t.getUnits().getMatches(Matches.enemyUnit(player, data));
final List<Unit> sortedUnitsList = new ArrayList<>(attackMap.get(t).getUnits());
sortedUnitsList.sort(new UnitBattleComparator(false, ProData.unitValueMap, TerritoryEffectHelper.getEffects(t), data, false, false));
Collections.reverse(sortedUnitsList);
final int powerWithout = DiceRoll.getTotalPower(DiceRoll.getUnitPowerAndRollsForNormalBattles(sortedUnitsList, defendingUnits, false, false, data, t, TerritoryEffectHelper.getEffects(t), false, null), data);
sortedUnitsList.add(o2.getKey());
sortedUnitsList.sort(new UnitBattleComparator(false, ProData.unitValueMap, TerritoryEffectHelper.getEffects(t), data, false, false));
Collections.reverse(sortedUnitsList);
final int powerWith = DiceRoll.getTotalPower(DiceRoll.getUnitPowerAndRollsForNormalBattles(sortedUnitsList, defendingUnits, false, false, data, t, TerritoryEffectHelper.getEffects(t), false, null), data);
final int power = powerWith - powerWithout;
if (power < minPower2) {
minPower2 = power;
}
}
}
final UnitAttachment ua2 = UnitAttachment.get(o2.getKey().getType());
if (ua2.getIsAir()) {
minPower2 *= 10;
}
final double attackEfficiency2 = (double) minPower2 / ProData.unitValueMap.getInt(o2.getKey().getType());
if (attackEfficiency1 != attackEfficiency2) {
return (attackEfficiency1 < attackEfficiency2) ? 1 : -1;
}
// Check if unit types are equal and is air then sort by average distance
if (o1.getKey().getType().equals(o2.getKey().getType())) {
final boolean isAirUnit = UnitAttachment.get(o1.getKey().getType()).getIsAir();
if (isAirUnit) {
int distance1 = 0;
for (final Territory t : o1.getValue()) {
if (!attackMap.get(t).isCurrentlyWins()) {
distance1 += data.getMap().getDistance_IgnoreEndForCondition(unitTerritoryMap.get(o1.getKey()), t, ProMatches.territoryCanMoveAirUnitsAndNoAa(player, data, true));
}
}
int distance2 = 0;
for (final Territory t : o2.getValue()) {
if (!attackMap.get(t).isCurrentlyWins()) {
distance2 += data.getMap().getDistance_IgnoreEndForCondition(unitTerritoryMap.get(o2.getKey()), t, ProMatches.territoryCanMoveAirUnitsAndNoAa(player, data, true));
}
}
if (distance1 != distance2) {
return distance1 - distance2;
}
}
}
return o1.getKey().getType().getName().compareTo(o2.getKey().getType().getName());
});
final Map<Unit, Set<Territory>> sortedUnitAttackOptions = new LinkedHashMap<>();
for (final Map.Entry<Unit, Set<Territory>> entry : list) {
sortedUnitAttackOptions.put(entry.getKey(), entry.getValue());
}
return sortedUnitAttackOptions;
}
use of games.strategy.triplea.ai.pro.data.ProTerritory in project triplea by triplea-game.
the class ProSimulateTurnUtils method transferMoveMap.
public static Map<Territory, ProTerritory> transferMoveMap(final Map<Territory, ProTerritory> moveMap, final GameData toData, final PlayerID player) {
ProLogger.info("Transferring move map");
final Map<Unit, Territory> unitTerritoryMap = ProData.unitTerritoryMap;
final Map<Territory, ProTerritory> result = new HashMap<>();
final List<Unit> usedUnits = new ArrayList<>();
for (final Territory fromTerritory : moveMap.keySet()) {
final Territory toTerritory = toData.getMap().getTerritory(fromTerritory.getName());
final ProTerritory patd = new ProTerritory(toTerritory);
result.put(toTerritory, patd);
final Map<Unit, List<Unit>> amphibAttackMap = moveMap.get(fromTerritory).getAmphibAttackMap();
final Map<Unit, Boolean> isTransportingMap = moveMap.get(fromTerritory).getIsTransportingMap();
final Map<Unit, Territory> transportTerritoryMap = moveMap.get(fromTerritory).getTransportTerritoryMap();
final Map<Unit, Territory> bombardMap = moveMap.get(fromTerritory).getBombardTerritoryMap();
ProLogger.debug("Transferring " + fromTerritory + " to " + toTerritory);
final List<Unit> amphibUnits = new ArrayList<>();
for (final Unit transport : amphibAttackMap.keySet()) {
final Unit toTransport;
final List<Unit> toUnits = new ArrayList<>();
if (isTransportingMap.get(transport)) {
toTransport = transferLoadedTransport(transport, amphibAttackMap.get(transport), unitTerritoryMap, usedUnits, toData, player);
toUnits.addAll(TransportTracker.transporting(toTransport));
} else {
toTransport = transferUnit(transport, unitTerritoryMap, usedUnits, toData, player);
for (final Unit u : amphibAttackMap.get(transport)) {
final Unit toUnit = transferUnit(u, unitTerritoryMap, usedUnits, toData, player);
toUnits.add(toUnit);
}
}
patd.addUnits(toUnits);
patd.putAmphibAttackMap(toTransport, toUnits);
amphibUnits.addAll(amphibAttackMap.get(transport));
if (transportTerritoryMap.get(transport) != null) {
patd.getTransportTerritoryMap().put(toTransport, toData.getMap().getTerritory(transportTerritoryMap.get(transport).getName()));
}
ProLogger.trace("---Transferring transport=" + transport + " with units=" + amphibAttackMap.get(transport) + " unloadTerritory=" + transportTerritoryMap.get(transport) + " to transport=" + toTransport + " with units=" + toUnits + " unloadTerritory=" + patd.getTransportTerritoryMap().get(toTransport));
}
for (final Unit u : moveMap.get(fromTerritory).getUnits()) {
if (!amphibUnits.contains(u)) {
final Unit toUnit = transferUnit(u, unitTerritoryMap, usedUnits, toData, player);
patd.addUnit(toUnit);
ProLogger.trace("---Transferring unit " + u + " to " + toUnit);
}
}
for (final Unit u : moveMap.get(fromTerritory).getBombers()) {
final Unit toUnit = transferUnit(u, unitTerritoryMap, usedUnits, toData, player);
patd.getBombers().add(toUnit);
ProLogger.trace("---Transferring bomber " + u + " to " + toUnit);
}
for (final Unit u : bombardMap.keySet()) {
final Unit toUnit = transferUnit(u, unitTerritoryMap, usedUnits, toData, player);
patd.getBombardTerritoryMap().put(toUnit, toData.getMap().getTerritory(bombardMap.get(u).getName()));
ProLogger.trace("---Transferring bombard=" + u + ", bombardFromTerritory=" + bombardMap.get(u) + " to bomard=" + toUnit + ", bombardFromTerritory=" + patd.getBombardTerritoryMap().get(toUnit));
}
}
return result;
}
Aggregations