use of games.strategy.engine.data.Territory in project triplea by triplea-game.
the class WeakAi method populateBomberCombat.
private static void populateBomberCombat(final GameData data, final List<Collection<Unit>> moveUnits, final List<Route> moveRoutes, final PlayerID player) {
final Predicate<Territory> enemyFactory = Matches.territoryIsEnemyNonNeutralAndHasEnemyUnitMatching(data, player, Matches.unitCanProduceUnitsAndCanBeDamaged());
final Predicate<Unit> ownBomber = Matches.unitIsStrategicBomber().and(Matches.unitIsOwnedBy(player));
for (final Territory t : data.getMap().getTerritories()) {
final Collection<Unit> bombers = t.getUnits().getMatches(ownBomber);
if (bombers.isEmpty()) {
continue;
}
final Predicate<Territory> routeCond = Matches.territoryHasEnemyAaForCombatOnly(player, data).negate();
final Route bombRoute = Utils.findNearest(t, enemyFactory, routeCond, data);
moveUnits.add(bombers);
moveRoutes.add(bombRoute);
}
}
use of games.strategy.engine.data.Territory in project triplea by triplea-game.
the class WeakAi method populateCombatMoveSea.
private static void populateCombatMoveSea(final GameData data, final List<Collection<Unit>> moveUnits, final List<Route> moveRoutes, final PlayerID player) {
final Collection<Unit> unitsAlreadyMoved = new HashSet<>();
for (final Territory t : data.getMap()) {
if (!t.isWater()) {
continue;
}
if (!t.getUnits().anyMatch(Matches.enemyUnit(player, data))) {
continue;
}
final float enemyStrength = AiUtils.strength(t.getUnits().getUnits(), false, true);
if (enemyStrength > 0) {
final Predicate<Unit> attackable = Matches.unitIsOwnedBy(player).and(o -> !unitsAlreadyMoved.contains(o));
final Set<Territory> dontMoveFrom = new HashSet<>();
// find our strength that we can attack with
float ourStrength = 0;
final Collection<Territory> attackFrom = data.getMap().getNeighbors(t, Matches.territoryIsWater());
for (final Territory owned : attackFrom) {
// dont risk units we are carrying
if (owned.getUnits().anyMatch(Matches.unitIsLand())) {
dontMoveFrom.add(owned);
continue;
}
ourStrength += AiUtils.strength(owned.getUnits().getMatches(attackable), true, true);
}
if (ourStrength > 1.32 * enemyStrength) {
for (final Territory owned : attackFrom) {
if (dontMoveFrom.contains(owned)) {
continue;
}
final List<Unit> units = owned.getUnits().getMatches(attackable);
unitsAlreadyMoved.addAll(units);
moveUnits.add(units);
moveRoutes.add(data.getMap().getRoute(owned, t));
}
}
}
}
}
use of games.strategy.engine.data.Territory in project triplea by triplea-game.
the class WeakAi method populateCombatMove.
private static void populateCombatMove(final GameData data, final List<Collection<Unit>> moveUnits, final List<Route> moveRoutes, final PlayerID player) {
populateBomberCombat(data, moveUnits, moveRoutes, player);
final Collection<Unit> unitsAlreadyMoved = new HashSet<>();
// find the territories we can just walk into
final Predicate<Territory> walkInto = Matches.isTerritoryEnemyAndNotUnownedWaterOrImpassableOrRestricted(player, data).or(Matches.isTerritoryFreeNeutral(data));
final List<Territory> enemyOwned = CollectionUtils.getMatches(data.getMap().getTerritories(), walkInto);
Collections.shuffle(enemyOwned);
enemyOwned.sort((o1, o2) -> {
// -1 means o1 goes first. 1 means o2 goes first. zero means they are equal.
if (Objects.equals(o1, o2)) {
return 0;
}
if (o1 == null) {
return 1;
}
if (o2 == null) {
return -1;
}
final TerritoryAttachment ta1 = TerritoryAttachment.get(o1);
final TerritoryAttachment ta2 = TerritoryAttachment.get(o2);
if (ta1 == null && ta2 == null) {
return 0;
}
if (ta1 == null) {
return 1;
}
if (ta2 == null) {
return -1;
}
// take capitols first if we can
if (ta1.isCapital() && !ta2.isCapital()) {
return -1;
}
if (!ta1.isCapital() && ta2.isCapital()) {
return 1;
}
final boolean factoryInT1 = o1.getUnits().anyMatch(Matches.unitCanProduceUnits());
final boolean factoryInT2 = o2.getUnits().anyMatch(Matches.unitCanProduceUnits());
// next take territories which can produce
if (factoryInT1 && !factoryInT2) {
return -1;
}
if (!factoryInT1 && factoryInT2) {
return 1;
}
final boolean infrastructureInT1 = o1.getUnits().anyMatch(Matches.unitIsInfrastructure());
final boolean infrastructureInT2 = o2.getUnits().anyMatch(Matches.unitIsInfrastructure());
// next take territories with infrastructure
if (infrastructureInT1 && !infrastructureInT2) {
return -1;
}
if (!infrastructureInT1 && infrastructureInT2) {
return 1;
}
// next take territories with largest PU value
return ta2.getProduction() - ta1.getProduction();
});
final List<Territory> isWaterTerr = Utils.onlyWaterTerr(enemyOwned);
enemyOwned.removeAll(isWaterTerr);
// first find the territories we can just walk into
for (final Territory enemy : enemyOwned) {
if (AiUtils.strength(enemy.getUnits().getUnits(), false, false) == 0) {
// only take it with 1 unit
boolean taken = false;
for (final Territory attackFrom : data.getMap().getNeighbors(enemy, Matches.territoryHasLandUnitsOwnedBy(player))) {
if (taken) {
break;
}
// get the cheapest unit to move in
final List<Unit> unitsSortedByCost = new ArrayList<>(attackFrom.getUnits().getUnits());
unitsSortedByCost.sort(AiUtils.getCostComparator());
for (final Unit unit : unitsSortedByCost) {
final Predicate<Unit> match = Matches.unitIsOwnedBy(player).and(Matches.unitIsLand()).and(Matches.unitIsNotInfrastructure()).and(Matches.unitCanMove()).and(Matches.unitIsNotAa()).and(Matches.unitCanNotMoveDuringCombatMove().negate());
if (!unitsAlreadyMoved.contains(unit) && match.test(unit)) {
moveRoutes.add(data.getMap().getRoute(attackFrom, enemy));
// number of units, to leave units free to move elsewhere
if (attackFrom.isWater()) {
final List<Unit> units = attackFrom.getUnits().getMatches(Matches.unitIsLandAndOwnedBy(player));
moveUnits.add(CollectionUtils.difference(units, unitsAlreadyMoved));
unitsAlreadyMoved.addAll(units);
} else {
moveUnits.add(Collections.singleton(unit));
}
unitsAlreadyMoved.add(unit);
taken = true;
break;
}
}
}
}
}
// find the territories we can reasonably expect to take
for (final Territory enemy : enemyOwned) {
final float enemyStrength = AiUtils.strength(enemy.getUnits().getUnits(), false, false);
if (enemyStrength > 0) {
final Predicate<Unit> attackable = Matches.unitIsOwnedBy(player).and(Matches.unitIsStrategicBomber().negate()).and(o -> !unitsAlreadyMoved.contains(o)).and(Matches.unitIsNotAa()).and(Matches.unitCanMove()).and(Matches.unitIsNotInfrastructure()).and(Matches.unitCanNotMoveDuringCombatMove().negate()).and(Matches.unitIsNotSea());
final Set<Territory> dontMoveFrom = new HashSet<>();
// find our strength that we can attack with
float ourStrength = 0;
final Collection<Territory> attackFrom = data.getMap().getNeighbors(enemy, Matches.territoryHasLandUnitsOwnedBy(player));
for (final Territory owned : attackFrom) {
if (TerritoryAttachment.get(owned) != null && TerritoryAttachment.get(owned).isCapital() && (Utils.getStrengthOfPotentialAttackers(owned, data) > AiUtils.strength(owned.getUnits().getUnits(), false, false))) {
dontMoveFrom.add(owned);
continue;
}
ourStrength += AiUtils.strength(owned.getUnits().getMatches(attackable), true, false);
}
// prevents 2 infantry from attacking 1 infantry
if (ourStrength > 1.37 * enemyStrength) {
// this is all we need to take it, dont go overboard, since we may be able to use the units to attack
// somewhere else
double remainingStrengthNeeded = (2.5 * enemyStrength) + 4;
for (final Territory owned : attackFrom) {
if (dontMoveFrom.contains(owned)) {
continue;
}
List<Unit> units = owned.getUnits().getMatches(attackable);
// 2) we can potentially attack another territory
if (!owned.isWater() && data.getMap().getNeighbors(owned, Matches.territoryHasEnemyLandUnits(player, data)).size() > 1) {
units = Utils.getUnitsUpToStrength(remainingStrengthNeeded, units, false);
}
remainingStrengthNeeded -= AiUtils.strength(units, true, false);
if (units.size() > 0) {
unitsAlreadyMoved.addAll(units);
moveUnits.add(units);
moveRoutes.add(data.getMap().getRoute(owned, enemy));
}
}
}
}
}
}
use of games.strategy.engine.data.Territory in project triplea by triplea-game.
the class WeakAi method getAmphibRoute.
private static Route getAmphibRoute(final PlayerID player, final GameData data) {
if (!isAmphibAttack(player, data)) {
return null;
}
final Territory ourCapitol = TerritoryAttachment.getFirstOwnedCapitalOrFirstUnownedCapital(player, data);
final Predicate<Territory> endMatch = o -> {
final boolean impassable = TerritoryAttachment.get(o) != null && TerritoryAttachment.get(o).getIsImpassable();
return !impassable && !o.isWater() && Utils.hasLandRouteToEnemyOwnedCapitol(o, player, data);
};
final Predicate<Territory> routeCond = Matches.territoryIsWater().and(Matches.territoryHasNoEnemyUnits(player, data));
final Route withNoEnemy = Utils.findNearest(ourCapitol, endMatch, routeCond, data);
if (withNoEnemy != null && withNoEnemy.numberOfSteps() > 0) {
return withNoEnemy;
}
// this will fail if our capitol is not next to water, c'est la vie.
final Route route = Utils.findNearest(ourCapitol, endMatch, Matches.territoryIsWater(), data);
if (route != null && route.numberOfSteps() == 0) {
return null;
}
return route;
}
use of games.strategy.engine.data.Territory in project triplea by triplea-game.
the class WeakAi method place.
@Override
public void place(final boolean bid, final IAbstractPlaceDelegate placeDelegate, final GameData data, final PlayerID player) {
if (player.getUnits().size() == 0) {
return;
}
final Territory capitol = TerritoryAttachment.getFirstOwnedCapitalOrFirstUnownedCapital(player, data);
// place in capitol first
placeAllWeCanOn(data, capitol, placeDelegate, player);
final List<Territory> randomTerritories = new ArrayList<>(data.getMap().getTerritories());
Collections.shuffle(randomTerritories);
for (final Territory t : randomTerritories) {
if (t != capitol && t.getOwner().equals(player) && t.getUnits().anyMatch(Matches.unitCanProduceUnits())) {
placeAllWeCanOn(data, t, placeDelegate, player);
}
}
}
Aggregations