28
28
import java .util .Objects ;
29
29
import java .util .Queue ;
30
30
import java .util .Set ;
31
+ import java .util .concurrent .ThreadLocalRandom ;
31
32
import java .util .function .Predicate ;
32
33
import javax .annotation .Nullable ;
33
34
import org .triplea .java .PredicateBuilder ;
@@ -45,37 +46,60 @@ static void tech(final ITechDelegate techDelegate, final GameData data, final Ga
45
46
final Territory myCapitol =
46
47
TerritoryAttachment .getFirstOwnedCapitalOrFirstUnownedCapital (player , data .getMap ());
47
48
final float enemyStrength = getStrengthOfPotentialAttackers (myCapitol , data , player );
48
- float myStrength =
49
- (myCapitol == null ) ? 0.0F : strength (myCapitol .getUnits (), false , false , false );
50
- final List <Territory > areaStrength = getNeighboringLandTerritories (data , player , myCapitol );
51
- for (final Territory areaTerr : areaStrength ) {
52
- myStrength += strength (areaTerr .getUnits (), false , false , false ) * 0.75F ;
53
- }
49
+ float myStrength = getMyStrength (data , player , myCapitol );
54
50
final boolean capDanger = myStrength < (enemyStrength * 1.25F + 3.0F );
55
51
final Resource pus = data .getResourceList ().getResource (Constants .PUS );
56
52
final int pusRemaining = player .getResources ().getQuantity (pus );
57
53
final Resource techTokens = data .getResourceList ().getResource (Constants .TECH_TOKENS );
58
54
final int techTokensQuantity = player .getResources ().getQuantity (techTokens );
55
+ final ThreadLocalRandom localRandom = ThreadLocalRandom .current ();
59
56
int tokensToBuy = 0 ;
60
- if (!capDanger && techTokensQuantity < 3 && pusRemaining > Math . random () * 160 ) {
57
+ if (!capDanger && techTokensQuantity < 3 && pusRemaining > localRandom . nextInt ( 160 ) ) {
61
58
tokensToBuy = 1 ;
62
59
}
63
60
if (techTokensQuantity > 0 || tokensToBuy > 0 ) {
64
61
final List <TechnologyFrontier > cats = TechAdvance .getPlayerTechCategories (player );
65
62
// retaining 65% chance of choosing land advances using basic ww2v3 model.
66
63
if (data .getTechnologyFrontier ().isEmpty ()) {
67
- if (Math . random () > 0.35 ) {
64
+ if (localRandom . nextFloat () > 0.35 ) {
68
65
techDelegate .rollTech (techTokensQuantity + tokensToBuy , cats .get (1 ), tokensToBuy , null );
69
66
} else {
70
67
techDelegate .rollTech (techTokensQuantity + tokensToBuy , cats .get (0 ), tokensToBuy , null );
71
68
}
72
69
} else {
73
- final int rand = (int ) (Math .random () * cats .size ());
74
- techDelegate .rollTech (techTokensQuantity + tokensToBuy , cats .get (rand ), tokensToBuy , null );
70
+ techDelegate .rollTech (
71
+ techTokensQuantity + tokensToBuy ,
72
+ cats .get (localRandom .nextInt (cats .size ())),
73
+ tokensToBuy ,
74
+ null );
75
75
}
76
76
}
77
77
}
78
78
79
+ /**
80
+ * Get strength value for territory {@code myCapitol} calculated from units in the territory and
81
+ * neighboring land territories (latter adjusted with a factor)
82
+ *
83
+ * @param data {@code GameData}
84
+ * @param player current {@code GamePlayer}
85
+ * @param myCapitol current {@code Territory}
86
+ * @return strength value for territory {@code myCapitol}
87
+ */
88
+ private static float getMyStrength (
89
+ final GameData data , final GamePlayer player , final Territory myCapitol ) {
90
+ if (myCapitol == null ) {
91
+ return 0.0F ;
92
+ }
93
+ final float capitolStrength = strength (myCapitol .getUnits (), false , false , false );
94
+ final List <Territory > neighboringLandTerritories =
95
+ getNeighboringLandTerritories (data , player , myCapitol );
96
+ final List <Unit > unitsOfNeighboringLandTerritories = new ArrayList <>();
97
+ neighboringLandTerritories .forEach (t -> unitsOfNeighboringLandTerritories .addAll (t .getUnits ()));
98
+ final float neighborStrength =
99
+ strength (unitsOfNeighboringLandTerritories , false , false , false ) * 0.75F ;
100
+ return capitolStrength + neighborStrength ;
101
+ }
102
+
79
103
/**
80
104
* Returns the strength of all attackers to a territory. Differentiates between sea and land
81
105
* attack Determines all transports within range of territory Determines all air units within
@@ -282,7 +306,7 @@ private static float getStrengthOfPotentialAttackers(
282
306
}
283
307
for (final GamePlayer enemyPlayerCandidate : enemyPlayers ) {
284
308
if (!Objects .equals (enemyPlayer , enemyPlayerCandidate )) {
285
- // give 40% of other players...this is will affect a lot of decisions by AI
309
+ // give 40% of other players...this will affect a lot of decisions by AI
286
310
maxStrength += enemyPlayerAttackMap .get (enemyPlayerCandidate ) * 0.40F ;
287
311
}
288
312
}
@@ -540,8 +564,8 @@ private static Route getMaxSeaRoute(
540
564
final Collection <Unit > units ,
541
565
final GamePlayer player ,
542
566
final int maxDistance ) {
543
- // note this does not care if subs are submerged or not
544
- // should it? does submerging affect movement of enemies?
567
+ // note this does not care if subs are submerged or not, should it?
568
+ // does submerging affect movement of enemies?
545
569
if (start == null || destination == null || !start .isWater () || !destination .isWater ()) {
546
570
return null ;
547
571
}
@@ -604,7 +628,7 @@ private static List<Territory> getExactNeighbors(
604
628
* Finds list of territories at exactly distance from the start.
605
629
*
606
630
* @param endCondition condition that all end points must satisfy
607
- * @param routeCondition condition that all traversed internal territories must satisfied
631
+ * @param routeCondition condition that all traversed internal territories must satisfy
608
632
*/
609
633
private static List <Territory > findFrontier (
610
634
final Territory start ,
0 commit comments