use of games.strategy.triplea.ai.pro.data.ProTerritory in project triplea by triplea-game.
the class ProBattleUtils method territoryHasLocalLandSuperiorityAfterMoves.
public static boolean territoryHasLocalLandSuperiorityAfterMoves(final Territory t, final int distance, final PlayerID player, final Map<Territory, ProTerritory> moveMap) {
final GameData data = ProData.getData();
// Find enemy strength
final Set<Territory> nearbyTerritoriesForEnemy = data.getMap().getNeighbors(t, distance, ProMatches.territoryCanMoveLandUnits(player, data, false));
nearbyTerritoriesForEnemy.add(t);
final List<Unit> enemyUnits = new ArrayList<>();
for (final Territory nearbyTerritory : nearbyTerritoriesForEnemy) {
enemyUnits.addAll(nearbyTerritory.getUnits().getMatches(ProMatches.unitIsEnemyNotNeutral(player, data)));
}
// Find allied strength
final Set<Territory> nearbyTerritoriesForAllied = data.getMap().getNeighbors(t, distance - 1, ProMatches.territoryCanMoveLandUnits(player, data, false));
nearbyTerritoriesForAllied.add(t);
final List<Unit> alliedUnits = new ArrayList<>();
for (final Territory nearbyTerritory : nearbyTerritoriesForAllied) {
if (moveMap.get(nearbyTerritory) != null) {
alliedUnits.addAll(moveMap.get(nearbyTerritory).getAllDefenders());
}
}
// Determine strength difference
final double strengthDifference = estimateStrengthDifference(t, enemyUnits, alliedUnits);
ProLogger.trace(t + ", current enemy land strengthDifference=" + strengthDifference + ", enemySize=" + enemyUnits.size() + ", alliedSize=" + alliedUnits.size());
return strengthDifference <= 50;
}
use of games.strategy.triplea.ai.pro.data.ProTerritory in project triplea by triplea-game.
the class ProMoveUtils method calculateAmphibRoutes.
public static void calculateAmphibRoutes(final PlayerID player, final List<Collection<Unit>> moveUnits, final List<Route> moveRoutes, final List<Collection<Unit>> transportsToLoad, final Map<Territory, ProTerritory> attackMap, final boolean isCombatMove) {
final GameData data = ProData.getData();
// Loop through all territories to attack
for (final Territory t : attackMap.keySet()) {
// Loop through each amphib attack map
final Map<Unit, List<Unit>> amphibAttackMap = attackMap.get(t).getAmphibAttackMap();
for (final Unit transport : amphibAttackMap.keySet()) {
int movesLeft = TripleAUnit.get(transport).getMovementLeft();
Territory transportTerritory = ProData.unitTerritoryMap.get(transport);
// Check if units are already loaded or not
final List<Unit> loadedUnits = new ArrayList<>();
final List<Unit> remainingUnitsToLoad = new ArrayList<>();
if (TransportTracker.isTransporting(transport)) {
loadedUnits.addAll(amphibAttackMap.get(transport));
} else {
remainingUnitsToLoad.addAll(amphibAttackMap.get(transport));
}
// Load units and move transport
while (movesLeft >= 0) {
// Load adjacent units if no enemies present in transport territory
if (Matches.territoryHasEnemyUnits(player, data).negate().test(transportTerritory)) {
final List<Unit> unitsToRemove = new ArrayList<>();
for (final Unit amphibUnit : remainingUnitsToLoad) {
if (data.getMap().getDistance(transportTerritory, ProData.unitTerritoryMap.get(amphibUnit)) == 1) {
moveUnits.add(Collections.singletonList(amphibUnit));
transportsToLoad.add(Collections.singletonList(transport));
final Route route = new Route(ProData.unitTerritoryMap.get(amphibUnit), transportTerritory);
moveRoutes.add(route);
unitsToRemove.add(amphibUnit);
loadedUnits.add(amphibUnit);
}
}
for (final Unit u : unitsToRemove) {
remainingUnitsToLoad.remove(u);
}
}
// Move transport if I'm not already at the end or out of moves
final Territory unloadTerritory = attackMap.get(t).getTransportTerritoryMap().get(transport);
int distanceFromEnd = data.getMap().getDistance(transportTerritory, t);
if (t.isWater()) {
distanceFromEnd++;
}
if (movesLeft > 0 && (distanceFromEnd > 1 || !remainingUnitsToLoad.isEmpty() || (unloadTerritory != null && !unloadTerritory.equals(transportTerritory)))) {
final Set<Territory> neighbors = data.getMap().getNeighbors(transportTerritory, ProMatches.territoryCanMoveSeaUnitsThrough(player, data, isCombatMove));
Territory territoryToMoveTo = null;
int minUnitDistance = Integer.MAX_VALUE;
// Used to move to farthest away loading territory first
int maxDistanceFromEnd = Integer.MIN_VALUE;
for (final Territory neighbor : neighbors) {
if (MoveValidator.validateCanal(new Route(transportTerritory, neighbor), Collections.singletonList(transport), player, data) != null) {
continue;
}
int distanceFromUnloadTerritory = 0;
if (unloadTerritory != null) {
distanceFromUnloadTerritory = data.getMap().getDistance_IgnoreEndForCondition(neighbor, unloadTerritory, ProMatches.territoryCanMoveSeaUnitsThrough(player, data, isCombatMove));
}
int neighborDistanceFromEnd = data.getMap().getDistance_IgnoreEndForCondition(neighbor, t, ProMatches.territoryCanMoveSeaUnitsThrough(player, data, isCombatMove));
if (t.isWater()) {
neighborDistanceFromEnd++;
}
int maxUnitDistance = 0;
for (final Unit u : remainingUnitsToLoad) {
final int distance = data.getMap().getDistance(neighbor, ProData.unitTerritoryMap.get(u));
if (distance > maxUnitDistance) {
maxUnitDistance = distance;
}
}
if (neighborDistanceFromEnd <= movesLeft && maxUnitDistance <= minUnitDistance && distanceFromUnloadTerritory < movesLeft && (maxUnitDistance < minUnitDistance || (maxUnitDistance > 1 && neighborDistanceFromEnd > maxDistanceFromEnd) || (maxUnitDistance <= 1 && neighborDistanceFromEnd < maxDistanceFromEnd))) {
territoryToMoveTo = neighbor;
minUnitDistance = maxUnitDistance;
if (neighborDistanceFromEnd > maxDistanceFromEnd) {
maxDistanceFromEnd = neighborDistanceFromEnd;
}
}
}
if (territoryToMoveTo != null) {
final List<Unit> unitsToMove = new ArrayList<>();
unitsToMove.add(transport);
unitsToMove.addAll(loadedUnits);
moveUnits.add(unitsToMove);
transportsToLoad.add(null);
final Route route = new Route(transportTerritory, territoryToMoveTo);
moveRoutes.add(route);
transportTerritory = territoryToMoveTo;
}
}
movesLeft--;
}
if (!remainingUnitsToLoad.isEmpty()) {
ProLogger.warn(data.getSequence().getRound() + "-" + data.getSequence().getStep().getName() + ": " + t + ", remainingUnitsToLoad=" + remainingUnitsToLoad);
}
// Set territory transport is moving to
attackMap.get(t).getTransportTerritoryMap().put(transport, transportTerritory);
// Unload transport
if (!loadedUnits.isEmpty() && !t.isWater()) {
moveUnits.add(loadedUnits);
transportsToLoad.add(null);
final Route route = new Route(transportTerritory, t);
moveRoutes.add(route);
}
}
}
}
use of games.strategy.triplea.ai.pro.data.ProTerritory in project triplea by triplea-game.
the class ProMoveUtils method calculateBombardMoveRoutes.
public static void calculateBombardMoveRoutes(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 ProTerritory t : attackMap.values()) {
// Loop through each unit that is attacking the current territory
for (final Unit u : t.getBombardTerritoryMap().keySet()) {
final Territory bombardFromTerritory = t.getBombardTerritoryMap().get(u);
// Skip if unit is already in move to territory
final Territory startTerritory = ProData.unitTerritoryMap.get(u);
if (startTerritory.equals(bombardFromTerritory)) {
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(ProMatches.unitCanBeMovedAndIsOwnedSea(player, true))) {
// Naval unit
route = data.getMap().getRoute_IgnoreEnd(startTerritory, bombardFromTerritory, ProMatches.territoryCanMoveSeaUnitsThrough(player, data, true));
}
moveRoutes.add(route);
}
}
}
use of games.strategy.triplea.ai.pro.data.ProTerritory in project triplea by triplea-game.
the class ProAi method purchase.
@Override
protected void purchase(final boolean purchaseForBid, final int pusToSpend, final IPurchaseDelegate purchaseDelegate, final GameData data, final PlayerID player) {
final long start = System.currentTimeMillis();
BattleCalculator.clearOolCache();
ProLogUi.notifyStartOfRound(data.getSequence().getRound(), player.getName());
initializeData();
if (pusToSpend <= 0) {
return;
}
if (purchaseForBid) {
calc.setData(data);
storedPurchaseTerritories = purchaseAi.bid(pusToSpend, purchaseDelegate, data);
} else {
// Repair factories
purchaseAi.repair(pusToSpend, purchaseDelegate, data, player);
// Check if any place territories exist
final Map<Territory, ProPurchaseTerritory> purchaseTerritories = ProPurchaseUtils.findPurchaseTerritories(player);
final List<Territory> possibleFactoryTerritories = CollectionUtils.getMatches(data.getMap().getTerritories(), ProMatches.territoryHasNoInfraFactoryAndIsNotConqueredOwnedLand(player, data));
if (purchaseTerritories.isEmpty() && possibleFactoryTerritories.isEmpty()) {
ProLogger.info("No possible place or factory territories owned so exiting purchase logic");
return;
}
ProLogger.info("Starting simulation for purchase phase");
// Setup data copy and delegates
GameData dataCopy;
try {
data.acquireReadLock();
dataCopy = GameDataUtils.cloneGameData(data, true);
} catch (final Throwable t) {
ProLogger.log(Level.WARNING, "Error trying to clone game data for simulating phases", t);
return;
} finally {
data.releaseReadLock();
}
calc.setData(dataCopy);
final PlayerID playerCopy = dataCopy.getPlayerList().getPlayerId(player.getName());
final IMoveDelegate moveDel = DelegateFinder.moveDelegate(dataCopy);
final IDelegateBridge bridge = new ProDummyDelegateBridge(this, playerCopy, dataCopy);
moveDel.setDelegateBridgeAndPlayer(bridge);
// Determine turn sequence
final List<GameStep> gameSteps = new ArrayList<>();
for (final GameStep gameStep : dataCopy.getSequence()) {
gameSteps.add(gameStep);
}
// Simulate the next phases until place/end of turn is reached then use simulated data for purchase
final int nextStepIndex = dataCopy.getSequence().getStepIndex() + 1;
for (int i = nextStepIndex; i < gameSteps.size(); i++) {
final GameStep step = gameSteps.get(i);
if (!playerCopy.equals(step.getPlayerId())) {
continue;
}
dataCopy.getSequence().setRoundAndStep(dataCopy.getSequence().getRound(), step.getDisplayName(), step.getPlayerId());
final String stepName = step.getName();
ProLogger.info("Simulating phase: " + stepName);
if (stepName.endsWith("NonCombatMove")) {
ProData.initializeSimulation(this, dataCopy, playerCopy);
final Map<Territory, ProTerritory> factoryMoveMap = nonCombatMoveAi.simulateNonCombatMove(moveDel);
if (storedFactoryMoveMap == null) {
storedFactoryMoveMap = ProSimulateTurnUtils.transferMoveMap(factoryMoveMap, data, player);
}
} else if (stepName.endsWith("CombatMove") && !stepName.endsWith("AirborneCombatMove")) {
ProData.initializeSimulation(this, dataCopy, playerCopy);
final Map<Territory, ProTerritory> moveMap = combatMoveAi.doCombatMove(moveDel);
if (storedCombatMoveMap == null) {
storedCombatMoveMap = ProSimulateTurnUtils.transferMoveMap(moveMap, data, player);
}
} else if (stepName.endsWith("Battle")) {
ProData.initializeSimulation(this, dataCopy, playerCopy);
ProSimulateTurnUtils.simulateBattles(dataCopy, playerCopy, bridge, calc);
} else if (stepName.endsWith("Place") || stepName.endsWith("EndTurn")) {
ProData.initializeSimulation(this, dataCopy, player);
storedPurchaseTerritories = purchaseAi.purchase(purchaseDelegate, data);
break;
} else if (stepName.endsWith("Politics")) {
ProData.initializeSimulation(this, dataCopy, player);
final PoliticsDelegate politicsDelegate = DelegateFinder.politicsDelegate(dataCopy);
politicsDelegate.setDelegateBridgeAndPlayer(bridge);
final List<PoliticalActionAttachment> actions = politicsAi.politicalActions();
if (storedPoliticalActions == null) {
storedPoliticalActions = actions;
}
}
}
}
ProLogger.info(player.getName() + " time for purchase=" + (System.currentTimeMillis() - start));
}
use of games.strategy.triplea.ai.pro.data.ProTerritory in project triplea by triplea-game.
the class ProCombatMoveAi method moveOneDefenderToLandTerritoriesBorderingEnemy.
private List<Unit> moveOneDefenderToLandTerritoriesBorderingEnemy(final List<ProTerritory> prioritizedTerritories) {
ProLogger.info("Determine which territories to defend with one land unit");
final Map<Unit, Set<Territory>> unitMoveMap = territoryManager.getAttackOptions().getUnitMoveMap();
// Get list of territories to attack
final List<Territory> territoriesToAttack = new ArrayList<>();
for (final ProTerritory patd : prioritizedTerritories) {
territoriesToAttack.add(patd.getTerritory());
}
// Find land territories with no can't move units and adjacent to enemy land units
final List<Unit> alreadyMovedUnits = new ArrayList<>();
for (final Territory t : ProData.myUnitTerritories) {
final boolean hasAlliedLandUnits = t.getUnits().anyMatch(ProMatches.unitCantBeMovedAndIsAlliedDefenderAndNotInfra(player, data, t));
final Set<Territory> enemyNeighbors = data.getMap().getNeighbors(t, Matches.territoryIsEnemyNonNeutralAndHasEnemyUnitMatching(data, player, Matches.unitIsLand()));
enemyNeighbors.removeAll(territoriesToAttack);
if (!t.isWater() && !hasAlliedLandUnits && !enemyNeighbors.isEmpty()) {
int minCost = Integer.MAX_VALUE;
Unit minUnit = null;
for (final Unit u : t.getUnits().getMatches(Matches.unitIsOwnedBy(player))) {
if (ProData.unitValueMap.getInt(u.getType()) < minCost) {
minCost = ProData.unitValueMap.getInt(u.getType());
minUnit = u;
}
}
if (minUnit != null) {
unitMoveMap.remove(minUnit);
alreadyMovedUnits.add(minUnit);
ProLogger.debug(t + ", added one land unit: " + minUnit);
}
}
}
return alreadyMovedUnits;
}
Aggregations