Skip to content

Commit

Permalink
Merge branch 'triplea-game:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
WCSumpton authored Aug 13, 2024
2 parents 766b659 + 870de56 commit fc78a88
Show file tree
Hide file tree
Showing 44 changed files with 497 additions and 485 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ subprojects {
ext {
apacheHttpComponentsVersion = "4.5.14"
assertjCoreVersion = '3.26.3'
awaitilityVersion = "4.2.1"
awaitilityVersion = "4.2.2"
caffeineVersion = "3.1.8"
checkstyleVersion = "8.45"
commonsIoVersion = "2.16.1"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ public class NeighborGetter implements Function<Territory, Collection<Territory>
public Collection<Territory> apply(final Territory territory) {
final UnitAttachment unitAttachment = unitType.getUnitAttachment();
final PredicateBuilder<Territory> territoryPredicate = PredicateBuilder.trueBuilder();
if (unitAttachment.getIsSea()) {
if (unitAttachment.isSea()) {
territoryPredicate.and(Territory::isWater);
} else if (!unitAttachment.getIsAir()) {
} else if (!unitAttachment.isAir()) {
territoryPredicate.and(Predicate.not(Territory::isWater));
}
return gameMap.getNeighbors(territory, territoryPredicate.build());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -105,15 +105,16 @@ public void accept(final AiPlayerDebugAction aiPlayerDebugAction) {
unitAttachment ->
unitAttachment.getDefense(defender) > 0
&& Matches.unitTypeIsLand().test((UnitType) unitAttachment.getAttachedTo()));
final ThreadLocalRandom localRandom = ThreadLocalRandom.current();
for (int i = 0; i < 4; i++) {
getRandomUnitType(offenseUnitTypes)
getRandomUnitType(localRandom, offenseUnitTypes)
.ifPresent(
unitType ->
attackingUnits.addAll(unitType.create(new Random().nextInt(10), offender)));
getRandomUnitType(defenseUnitTypes)
attackingUnits.addAll(unitType.create(localRandom.nextInt(10), offender)));
getRandomUnitType(localRandom, defenseUnitTypes)
.ifPresent(
unitType ->
defendingUnits.addAll(unitType.create(new Random().nextInt(10), defender)));
defendingUnits.addAll(unitType.create(localRandom.nextInt(10), defender)));
}

System.out.println("Attack Units: " + MyFormatter.unitsToText(attackingUnits));
Expand Down Expand Up @@ -192,7 +193,8 @@ private Collection<UnitType> getUnitTypes(
.collect(Collectors.toSet());
}

private Optional<UnitType> getRandomUnitType(final Collection<UnitType> unitTypes) {
return unitTypes.stream().skip((int) (unitTypes.size() * Math.random())).findFirst();
private Optional<UnitType> getRandomUnitType(
final ThreadLocalRandom localRandom, final Collection<UnitType> unitTypes) {
return unitTypes.stream().skip((localRandom.nextInt(unitTypes.size()))).findFirst();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ private static void generatePerPlayer(final Parameters parameters, final GamePla
private static void generatePerPlayerAndUnit(
final Parameters parameters, final GamePlayer player, final UnitType unitType) {
final UnitAttachment unitAttachment = unitType.getUnitAttachment();
if (unitAttachment.getIsAaForCombatOnly()) {
if (unitAttachment.isAaForCombatOnly()) {
createAaUnitAbilities(parameters, player, unitType);
}
createUnitAbilities(parameters, player, unitType);
Expand Down Expand Up @@ -217,7 +217,7 @@ private static CombatUnitAbility.Suicide calculateSuicideType(
? unitAttachment.getIsSuicideOnAttack()
: unitAttachment.getIsSuicideOnDefense()) {
return CombatUnitAbility.Suicide.AFTER_FIRE;
} else if (unitAttachment.getIsSuicideOnHit()) {
} else if (unitAttachment.isSuicideOnHit()) {
return CombatUnitAbility.Suicide.AFTER_HIT;
} else {
return CombatUnitAbility.Suicide.NONE;
Expand Down Expand Up @@ -370,8 +370,7 @@ private static List<UnitType> getTargetsWithoutDestroyer(
}

private static Predicate<UnitType> isNotInfrastructure() {
return Predicate.not(
possibleTarget -> possibleTarget.getUnitAttachment().getIsInfrastructure());
return Predicate.not(possibleTarget -> possibleTarget.getUnitAttachment().isInfrastructure());
}

private static void createAntiFirstStrikeAbility(
Expand Down Expand Up @@ -402,7 +401,7 @@ private static void createAntiFirstStrikeAbility(

private static Collection<UnitType> getIsDestroyerUnitTypes(final UnitTypeList unitTypeList) {
return unitTypeList.stream()
.filter(unitType -> unitType.getUnitAttachment().getIsDestroyer())
.filter(unitType -> unitType.getUnitAttachment().isDestroyer())
.collect(Collectors.toList());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public static float strength(
float strength = 0;
for (final Unit u : units) {
final UnitAttachment unitAttachment = u.getUnitAttachment();
if (!unitAttachment.getIsInfrastructure() && unitAttachment.getIsSea() == sea) {
if (!unitAttachment.isInfrastructure() && unitAttachment.isSea() == sea) {
// 2 points since we can absorb a hit
strength += 2;
// two hit
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -877,7 +877,7 @@ private void determineUnitsToAttackWith(

// Set air units in any territory with no AA (don't move planes to empty territories)
for (final Unit unit : sortedUnitAttackOptions.keySet()) {
final boolean isAirUnit = unit.getUnitAttachment().getIsAir();
final boolean isAirUnit = unit.getUnitAttachment().isAir();
if (!isAirUnit) {
continue; // skip non-air units
}
Expand Down Expand Up @@ -965,7 +965,7 @@ private void determineUnitsToAttackWith(

// Add sea units to any territory that significantly increases TUV gain
for (final Unit unit : sortedUnitAttackOptions.keySet()) {
final boolean isSeaUnit = unit.getUnitAttachment().getIsSea();
final boolean isSeaUnit = unit.getUnitAttachment().isSea();
if (!isSeaUnit) {
continue; // skip non-sea units
}
Expand Down Expand Up @@ -1285,7 +1285,7 @@ private Map<Unit, Set<Territory>> tryToAttackTerritories(

// Try to set at least one destroyer in each sea territory with subs
for (final Unit unit : sortedUnitAttackOptions.keySet()) {
final boolean isDestroyerUnit = unit.getUnitAttachment().getIsDestroyer();
final boolean isDestroyerUnit = unit.getUnitAttachment().isDestroyer();
if (!isDestroyerUnit) {
continue; // skip non-destroyer units
}
Expand All @@ -1306,7 +1306,7 @@ private Map<Unit, Set<Territory>> tryToAttackTerritories(

// Set enough land and sea units in territories to have at least a chance of winning
for (final Unit unit : sortedUnitAttackOptions.keySet()) {
final boolean isAirUnit = unit.getUnitAttachment().getIsAir();
final boolean isAirUnit = unit.getUnitAttachment().isAir();
final boolean isExpensiveLandUnit =
Matches.unitIsLand().test(unit)
&& proData.getUnitValue(unit.getType()) > 2 * proData.getMinCostPerHitPoint();
Expand Down Expand Up @@ -1346,7 +1346,7 @@ private Map<Unit, Set<Territory>> tryToAttackTerritories(

// Set non-air units in territories that can be held
for (final Unit unit : sortedUnitAttackOptions.keySet()) {
final boolean isAirUnit = unit.getUnitAttachment().getIsAir();
final boolean isAirUnit = unit.getUnitAttachment().isAir();
if (isAirUnit || addedUnits.contains(unit)) {
continue; // skip air units
}
Expand Down Expand Up @@ -1383,7 +1383,7 @@ private Map<Unit, Set<Territory>> tryToAttackTerritories(

// Set air units in territories that can't be held (don't move planes to empty territories)
for (final Unit unit : sortedUnitAttackOptions.keySet()) {
final boolean isAirUnit = unit.getUnitAttachment().getIsAir();
final boolean isAirUnit = unit.getUnitAttachment().isAir();
if (!isAirUnit) {
continue; // skip non-air units
}
Expand Down Expand Up @@ -1455,7 +1455,7 @@ private Map<Unit, Set<Territory>> tryToAttackTerritories(
if (addedUnits.contains(unit)) {
continue;
}
final boolean isAirUnit = unit.getUnitAttachment().getIsAir();
final boolean isAirUnit = unit.getUnitAttachment().isAir();
Territory minWinTerritory = null;
double minWinPercentage = proData.getWinPercentage();
for (final Territory t : sortedUnitAttackOptions.get(unit)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -763,7 +763,7 @@ private void moveUnitsToDefendTerritories(

// Set enough units in territories to have at least a chance of winning
for (final Unit unit : sortedUnitMoveOptions.keySet()) {
final boolean isAirUnit = unit.getUnitAttachment().getIsAir();
final boolean isAirUnit = unit.getUnitAttachment().isAir();
if (isAirUnit || Matches.unitIsCarrier().test(unit) || addedUnits.contains(unit)) {
continue; // skip air and carrier units
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import java.util.Objects;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.ThreadLocalRandom;
import java.util.function.Predicate;
import javax.annotation.Nullable;
import org.triplea.java.PredicateBuilder;
Expand All @@ -45,37 +46,60 @@ static void tech(final ITechDelegate techDelegate, final GameData data, final Ga
final Territory myCapitol =
TerritoryAttachment.getFirstOwnedCapitalOrFirstUnownedCapital(player, data.getMap());
final float enemyStrength = getStrengthOfPotentialAttackers(myCapitol, data, player);
float myStrength =
(myCapitol == null) ? 0.0F : strength(myCapitol.getUnits(), false, false, false);
final List<Territory> areaStrength = getNeighboringLandTerritories(data, player, myCapitol);
for (final Territory areaTerr : areaStrength) {
myStrength += strength(areaTerr.getUnits(), false, false, false) * 0.75F;
}
float myStrength = getMyStrength(data, player, myCapitol);
final boolean capDanger = myStrength < (enemyStrength * 1.25F + 3.0F);
final Resource pus = data.getResourceList().getResource(Constants.PUS);
final int pusRemaining = player.getResources().getQuantity(pus);
final Resource techTokens = data.getResourceList().getResource(Constants.TECH_TOKENS);
final int techTokensQuantity = player.getResources().getQuantity(techTokens);
final ThreadLocalRandom localRandom = ThreadLocalRandom.current();
int tokensToBuy = 0;
if (!capDanger && techTokensQuantity < 3 && pusRemaining > Math.random() * 160) {
if (!capDanger && techTokensQuantity < 3 && pusRemaining > localRandom.nextInt(160)) {
tokensToBuy = 1;
}
if (techTokensQuantity > 0 || tokensToBuy > 0) {
final List<TechnologyFrontier> cats = TechAdvance.getPlayerTechCategories(player);
// retaining 65% chance of choosing land advances using basic ww2v3 model.
if (data.getTechnologyFrontier().isEmpty()) {
if (Math.random() > 0.35) {
if (localRandom.nextFloat() > 0.35) {
techDelegate.rollTech(techTokensQuantity + tokensToBuy, cats.get(1), tokensToBuy, null);
} else {
techDelegate.rollTech(techTokensQuantity + tokensToBuy, cats.get(0), tokensToBuy, null);
}
} else {
final int rand = (int) (Math.random() * cats.size());
techDelegate.rollTech(techTokensQuantity + tokensToBuy, cats.get(rand), tokensToBuy, null);
techDelegate.rollTech(
techTokensQuantity + tokensToBuy,
cats.get(localRandom.nextInt(cats.size())),
tokensToBuy,
null);
}
}
}

/**
* Get strength value for territory {@code myCapitol} calculated from units in the territory and
* neighboring land territories (latter adjusted with a factor)
*
* @param data {@code GameData}
* @param player current {@code GamePlayer}
* @param myCapitol current {@code Territory}
* @return strength value for territory {@code myCapitol}
*/
private static float getMyStrength(
final GameData data, final GamePlayer player, final Territory myCapitol) {
if (myCapitol == null) {
return 0.0F;
}
final float capitolStrength = strength(myCapitol.getUnits(), false, false, false);
final List<Territory> neighboringLandTerritories =
getNeighboringLandTerritories(data, player, myCapitol);
final List<Unit> unitsOfNeighboringLandTerritories = new ArrayList<>();
neighboringLandTerritories.forEach(t -> unitsOfNeighboringLandTerritories.addAll(t.getUnits()));
final float neighborStrength =
strength(unitsOfNeighboringLandTerritories, false, false, false) * 0.75F;
return capitolStrength + neighborStrength;
}

/**
* Returns the strength of all attackers to a territory. Differentiates between sea and land
* attack Determines all transports within range of territory Determines all air units within
Expand Down Expand Up @@ -282,7 +306,7 @@ private static float getStrengthOfPotentialAttackers(
}
for (final GamePlayer enemyPlayerCandidate : enemyPlayers) {
if (!Objects.equals(enemyPlayer, enemyPlayerCandidate)) {
// give 40% of other players...this is will affect a lot of decisions by AI
// give 40% of other players...this will affect a lot of decisions by AI
maxStrength += enemyPlayerAttackMap.get(enemyPlayerCandidate) * 0.40F;
}
}
Expand Down Expand Up @@ -311,8 +335,8 @@ private static float strength(
}
for (final Unit u : units) {
final UnitAttachment unitAttachment = u.getUnitAttachment();
if (unitAttachment.getIsInfrastructure()) {
if (unitAttachment.getIsSea() == sea) {
if (unitAttachment.isInfrastructure()) {
if (unitAttachment.isSea() == sea) {
final int unitAttack = unitAttachment.getAttack(u.getOwner());
// BB = 6.0; AC=2.0/4.0; SUB=3.0; DS=4.0; TR=0.50/2.0; F=4.0/5.0; B=5.0/2.0;
// played with this value a good bit
Expand All @@ -330,7 +354,7 @@ private static float strength(
// only allow transport to have 0.35 on defense; none on attack
strength -= 0.50F;
}
} else if (unitAttachment.getIsAir() == sea) {
} else if (unitAttachment.isAir() == sea) {
strength += 1.00F;
if (attacking) {
strength +=
Expand Down Expand Up @@ -540,8 +564,8 @@ private static Route getMaxSeaRoute(
final Collection<Unit> units,
final GamePlayer player,
final int maxDistance) {
// note this does not care if subs are submerged or not
// should it? does submerging affect movement of enemies?
// note this does not care if subs are submerged or not, should it?
// does submerging affect movement of enemies?
if (start == null || destination == null || !start.isWater() || !destination.isWater()) {
return null;
}
Expand Down Expand Up @@ -604,7 +628,7 @@ private static List<Territory> getExactNeighbors(
* Finds list of territories at exactly distance from the start.
*
* @param endCondition condition that all end points must satisfy
* @param routeCondition condition that all traversed internal territories must satisfied
* @param routeCondition condition that all traversed internal territories must satisfy
*/
private static List<Territory> findFrontier(
final Territory start,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,13 @@ public class ProPurchaseOption {
final Resource pus = data.getResourceList().getResource(Constants.PUS);
cost = productionRule.getCosts().getInt(pus);
costs = productionRule.getCosts();
isConstruction = unitAttachment.getIsConstruction();
isConstruction = unitAttachment.isConstruction();
constructionType = unitAttachment.getConstructionType();
constructionTypePerTurn = unitAttachment.getConstructionsPerTerrPerTypePerTurn();
maxConstructionType = unitAttachment.getMaxConstructionsPerTypePerTerr();
movement = unitAttachment.getMovement(player);
quantity = productionRule.getResults().totalValues();
final boolean isInfra = unitAttachment.getIsInfrastructure();
final boolean isInfra = unitAttachment.isInfrastructure();
hitPoints = unitAttachment.getHitPoints() * quantity;
if (isInfra) {
hitPoints = 0;
Expand All @@ -91,9 +91,9 @@ public class ProPurchaseOption {
defense = (double) unitAttachment.getDefense(player) * quantity;
transportCost = unitAttachment.getTransportCost() * quantity;
carrierCost = unitAttachment.getCarrierCost() * quantity;
isAir = unitAttachment.getIsAir();
isAir = unitAttachment.isAir();
isSub = unitAttachment.getCanEvade();
isDestroyer = unitAttachment.getIsDestroyer();
isDestroyer = unitAttachment.isDestroyer();
isTransport = unitAttachment.getTransportCapacity() > 0;
isLandTransport = unitAttachment.isLandTransport();
isCarrier = unitAttachment.getCarrierCapacity() > 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,7 @@ public ProPurchaseOptionMap(final GamePlayer player, final GameData data) {
final UnitType unitType = (UnitType) resourceOrUnit;

// Add rule to appropriate purchase option list
if (unitType.getUnitAttachment().getIsSuicideOnHit()
|| canUnitTypeSuicide(unitType, player)) {
if (unitType.getUnitAttachment().isSuicideOnHit() || canUnitTypeSuicide(unitType, player)) {
final ProPurchaseOption ppo = new ProPurchaseOption(rule, unitType, player, data);
specialOptions.add(ppo);
ProLogger.debug("Special: " + ppo);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ public static Map<Unit, Set<Territory>> sortUnitNeededOptionsThenAttack(
final UnitType unitType2 = u2.getType();

// If unit types are equal and are air, then sort by average distance.
if (unitType1.equals(unitType2) && unitType1.getUnitAttachment().getIsAir()) {
if (unitType1.equals(unitType2) && unitType1.getUnitAttachment().isAir()) {
final Predicate<Territory> predicate =
ProMatches.territoryCanMoveAirUnitsAndNoAa(data, player, true);
final Territory territory1 = unitTerritoryMap.get(u1);
Expand Down Expand Up @@ -231,7 +231,7 @@ private static double calculateAttackEfficiency(
minPower = powerDifference;
}
}
if (unit.getUnitAttachment().getIsAir()) {
if (unit.getUnitAttachment().isAir()) {
minPower *= 10;
}
final double unitValue = proData.getUnitValue(unit.getType());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ private List<MoveDescription> calculateTransportLoad(
while (iter.hasNext() && free > 0) {
final Unit current = iter.next();
final UnitAttachment ua = current.getUnitAttachment();
if (ua.getIsAir()) {
if (ua.isAir()) {
continue;
}
if (ua.getTransportCost() <= free) {
Expand Down
Loading

0 comments on commit fc78a88

Please sign in to comment.