chooseMilitaryUnit optimized!

This commit is contained in:
Yair Morgenstern 2022-02-10 14:42:52 +02:00
parent 86450c54eb
commit 8ee2a34a4d
2 changed files with 14 additions and 14 deletions

View File

@ -81,12 +81,12 @@ object Automation {
} }
fun chooseMilitaryUnit(city: CityInfo): String? { fun chooseMilitaryUnit(city: CityInfo): String? {
var militaryUnits = val currentChoice = city.cityConstructions.getCurrentConstruction()
city.cityConstructions.getConstructableUnits().filter { !it.isCivilian() } if (currentChoice is BaseUnit && !currentChoice.isCivilian()) return city.cityConstructions.currentConstructionFromQueue
.filter { allowSpendingResource(city.civInfo, it) }
if (militaryUnits.map { it.name } var militaryUnits = city.getRuleset().units.values.asSequence()
.contains(city.cityConstructions.currentConstructionFromQueue)) .filter { !it.isCivilian() }
return city.cityConstructions.currentConstructionFromQueue .filter { allowSpendingResource(city.civInfo, it) }
val findWaterConnectedCitiesAndEnemies = val findWaterConnectedCitiesAndEnemies =
BFS(city.getCenterTile()) { it.isWater || it.isCityCenter() } BFS(city.getCenterTile()) { it.isWater || it.isCityCenter() }
@ -105,6 +105,9 @@ object Automation {
if (providesUnneededCarryingSlots(unit, city.civInfo)) if (providesUnneededCarryingSlots(unit, city.civInfo))
militaryUnits = militaryUnits.filterNot { it == unit } militaryUnits = militaryUnits.filterNot { it == unit }
// Only now do we filter out the constructable units because that's a heavier check
militaryUnits = militaryUnits.filter { it.isBuildable(city.cityConstructions) }.toList().asSequence() // gather once because we have a .any afterwards
val chosenUnit: BaseUnit val chosenUnit: BaseUnit
if (!city.civInfo.isAtWar() if (!city.civInfo.isAtWar()
&& city.civInfo.cities.any { it.getCenterTile().militaryUnit == null } && city.civInfo.cities.any { it.getCenterTile().militaryUnit == null }
@ -117,14 +120,13 @@ object Automation {
val availableTypes = militaryUnits val availableTypes = militaryUnits
.map { it.unitType } .map { it.unitType }
.distinct() .distinct()
.toList() if (availableTypes.none()) return null
if (availableTypes.isEmpty()) return null
val bestUnitsForType = availableTypes.map { type -> militaryUnits val bestUnitsForType = availableTypes.map { type -> militaryUnits
.filter { unit -> unit.unitType == type } .filter { unit -> unit.unitType == type }
.maxByOrNull { unit -> unit.cost }!! } .maxByOrNull { unit -> unit.cost }!! }
// Check the maximum force evaluation for the shortlist so we can prune useless ones (ie scouts) // Check the maximum force evaluation for the shortlist so we can prune useless ones (ie scouts)
val bestForce = bestUnitsForType.maxOf { it.getForceEvaluation() } val bestForce = bestUnitsForType.maxOf { it.getForceEvaluation() }
chosenUnit = bestUnitsForType.filter { it.uniqueTo != null || it.getForceEvaluation() > bestForce / 3 }.random() chosenUnit = bestUnitsForType.filter { it.uniqueTo != null || it.getForceEvaluation() > bestForce / 3 }.toList().random()
} }
return chosenUnit.name return chosenUnit.name
} }

View File

@ -351,7 +351,7 @@ class BaseUnit : RulesetObject(), INonPerpetualConstruction {
if (isWaterUnit() && !cityConstructions.cityInfo.isCoastal()) if (isWaterUnit() && !cityConstructions.cityInfo.isCoastal())
rejectionReasons.add(RejectionReason.WaterUnitsInCoastalCities) rejectionReasons.add(RejectionReason.WaterUnitsInCoastalCities)
val civInfo = cityConstructions.cityInfo.civInfo val civInfo = cityConstructions.cityInfo.civInfo
for (unique in uniqueObjects.filter { it.type == UniqueType.NotDisplayedWithout }) { for (unique in getMatchingUniques(UniqueType.NotDisplayedWithout)) {
val filter = unique.params[0] val filter = unique.params[0]
if (filter in civInfo.gameInfo.ruleSet.tileResources && !civInfo.hasResource(filter) if (filter in civInfo.gameInfo.ruleSet.tileResources && !civInfo.hasResource(filter)
|| filter in civInfo.gameInfo.ruleSet.buildings && !cityConstructions.containsBuildingOrEquivalent(filter)) || filter in civInfo.gameInfo.ruleSet.buildings && !cityConstructions.containsBuildingOrEquivalent(filter))
@ -387,8 +387,7 @@ class BaseUnit : RulesetObject(), INonPerpetualConstruction {
if (!civInfo.gameInfo.gameParameters.nuclearWeaponsEnabled && isNuclearWeapon()) if (!civInfo.gameInfo.gameParameters.nuclearWeaponsEnabled && isNuclearWeapon())
rejectionReasons.add(RejectionReason.DisabledBySetting) rejectionReasons.add(RejectionReason.DisabledBySetting)
for (unique in uniqueObjects) { for (unique in getMatchingUniques("Unlocked with []") + getMatchingUniques("Requires []")) {
if (unique.placeholderText != "Unlocked with []" && unique.placeholderText != "Requires []") continue
val filter = unique.params[0] val filter = unique.params[0]
when { when {
ruleSet.technologies.contains(filter) -> ruleSet.technologies.contains(filter) ->
@ -415,8 +414,7 @@ class BaseUnit : RulesetObject(), INonPerpetualConstruction {
} }
} }
if (hasUnique(UniqueType.FoundCity) && if ((civInfo.isCityState() || civInfo.isOneCityChallenger()) && hasUnique(UniqueType.FoundCity)
(civInfo.isCityState() || civInfo.isOneCityChallenger())
) { ) {
rejectionReasons.add(RejectionReason.NoSettlerForOneCityPlayers) rejectionReasons.add(RejectionReason.NoSettlerForOneCityPlayers)
} }