mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-26 13:27:22 -04:00
Allocation and runtime optimization with sequences
This commit is contained in:
parent
8f231cd6e1
commit
47e998269a
@ -101,7 +101,7 @@ class Automation {
|
||||
chosenUnit = militaryUnits.filter { it.unitType== UnitType.Ranged }.maxBy { it.cost }!!
|
||||
|
||||
else{ // randomize type of unit and take the most expensive of its kind
|
||||
val chosenUnitType = militaryUnits.map { it.unitType }.distinct().filterNot{it==UnitType.Scout}.random()
|
||||
val chosenUnitType = militaryUnits.map { it.unitType }.distinct().filterNot{it==UnitType.Scout}.toList().random()
|
||||
chosenUnit = militaryUnits.filter { it.unitType==chosenUnitType }.maxBy { it.cost }!!
|
||||
}
|
||||
return chosenUnit.name
|
||||
|
@ -18,8 +18,10 @@ class ConstructionAutomation(val cityConstructions: CityConstructions){
|
||||
val cityInfo = cityConstructions.cityInfo
|
||||
val civInfo = cityInfo.civInfo
|
||||
|
||||
val buildableNotWonders = cityConstructions.getBuildableBuildings().filterNot { it.isWonder || it.isNationalWonder }
|
||||
val buildableWonders = cityConstructions.getBuildableBuildings().filter { it.isWonder || it.isNationalWonder }
|
||||
val buildableNotWonders = cityConstructions.getBuildableBuildings()
|
||||
.filterNot { it.isWonder || it.isNationalWonder }
|
||||
val buildableWonders = cityConstructions.getBuildableBuildings()
|
||||
.filter { it.isWonder || it.isNationalWonder }
|
||||
|
||||
val civUnits = civInfo.getCivUnits()
|
||||
val militaryUnits = civUnits.filter { !it.type.isCivilian()}.size
|
||||
@ -118,6 +120,7 @@ class ConstructionAutomation(val cityConstructions: CityConstructions){
|
||||
private fun addWorkerChoice() {
|
||||
if(civInfo.getIdleUnits().any { it.name==Constants.worker && it.action== Constants.unitActionAutomation})
|
||||
return // If we have automated workers who have no work to do then it's silly to construct new workers.
|
||||
|
||||
val citiesCountedTowardsWorkers = min(5, cities) // above 5 cities, extra cities won't make us want more workers
|
||||
if (workers < citiesCountedTowardsWorkers * 0.6f && civUnits.none { it.name==Constants.worker && it.isIdle() }) {
|
||||
var modifier = citiesCountedTowardsWorkers / (workers + 0.1f)
|
||||
@ -127,7 +130,8 @@ class ConstructionAutomation(val cityConstructions: CityConstructions){
|
||||
}
|
||||
|
||||
private fun addCultureBuildingChoice() {
|
||||
val cultureBuilding = buildableNotWonders.filter { it.isStatRelated(Stat.Culture) }.minBy { it.cost }
|
||||
val cultureBuilding = buildableNotWonders
|
||||
.filter { it.isStatRelated(Stat.Culture) }.minBy { it.cost }
|
||||
if (cultureBuilding != null) {
|
||||
var modifier = 0.5f
|
||||
if(cityInfo.cityStats.currentCityStats.culture==0f) // It won't grow if we don't help it
|
||||
@ -149,7 +153,7 @@ class ConstructionAutomation(val cityConstructions: CityConstructions){
|
||||
}
|
||||
|
||||
private fun addWondersChoice() {
|
||||
if (buildableWonders.isNotEmpty()) {
|
||||
if (buildableWonders.any()) {
|
||||
fun getWonderPriority(wonder: Building): Float {
|
||||
if (preferredVictoryType == VictoryType.Cultural
|
||||
&& wonder.name in listOf("Sistine Chapel", "Eiffel Tower", "Cristo Redentor", "Neuschwanstein", "Sydney Opera House"))
|
||||
@ -167,21 +171,20 @@ class ConstructionAutomation(val cityConstructions: CityConstructions){
|
||||
return 1f
|
||||
}
|
||||
|
||||
val wondersByPriority = buildableWonders
|
||||
.sortedByDescending { getWonderPriority(it) }
|
||||
val wonder = wondersByPriority.first()
|
||||
val highestPriorityWonder = buildableWonders
|
||||
.maxBy { getWonderPriority(it) }!!
|
||||
val citiesBuildingWonders = civInfo.cities
|
||||
.count { it.cityConstructions.isBuildingWonder() }
|
||||
|
||||
var modifier = 2f * getWonderPriority(wonder) / (citiesBuildingWonders + 1)
|
||||
var modifier = 2f * getWonderPriority(highestPriorityWonder) / (citiesBuildingWonders + 1)
|
||||
if (!cityIsOverAverageProduction) modifier /= 5 // higher production cities will deal with this
|
||||
addChoice(relativeCostEffectiveness, wonder.name, modifier)
|
||||
addChoice(relativeCostEffectiveness, highestPriorityWonder.name, modifier)
|
||||
}
|
||||
}
|
||||
|
||||
private fun addUnitTrainingBuildingChoice() {
|
||||
val unitTrainingBuilding = buildableNotWonders.filter { it.xpForNewUnits > 0 }
|
||||
.minBy { it.cost }
|
||||
val unitTrainingBuilding = buildableNotWonders.asSequence()
|
||||
.filter { it.xpForNewUnits > 0 }.minBy { it.cost }
|
||||
if (unitTrainingBuilding != null && (preferredVictoryType != VictoryType.Cultural || isAtWar)) {
|
||||
var modifier = if (cityIsOverAverageProduction) 0.5f else 0.1f // You shouldn't be cranking out units anytime soon
|
||||
if (isAtWar) modifier *= 2
|
||||
@ -192,8 +195,8 @@ class ConstructionAutomation(val cityConstructions: CityConstructions){
|
||||
}
|
||||
|
||||
private fun addDefenceBuildingChoice() {
|
||||
val defensiveBuilding = buildableNotWonders.filter { it.cityStrength > 0 }
|
||||
.minBy { it.cost }
|
||||
val defensiveBuilding = buildableNotWonders.asSequence()
|
||||
.filter { it.cityStrength > 0 }.minBy { it.cost }
|
||||
if (defensiveBuilding != null && (isAtWar || preferredVictoryType != VictoryType.Cultural)) {
|
||||
var modifier = 0.2f
|
||||
if (isAtWar) modifier = 0.5f
|
||||
@ -208,7 +211,7 @@ class ConstructionAutomation(val cityConstructions: CityConstructions){
|
||||
}
|
||||
|
||||
private fun addHappinessBuildingChoice() {
|
||||
val happinessBuilding = buildableNotWonders
|
||||
val happinessBuilding = buildableNotWonders.asSequence()
|
||||
.filter { it.isStatRelated(Stat.Happiness)
|
||||
|| it.uniques.contains("Remove extra unhappiness from annexed cities") }
|
||||
.minBy { it.cost }
|
||||
@ -222,7 +225,8 @@ class ConstructionAutomation(val cityConstructions: CityConstructions){
|
||||
}
|
||||
|
||||
private fun addScienceBuildingChoice() {
|
||||
val scienceBuilding = buildableNotWonders.filter { it.isStatRelated(Stat.Science) || it.name=="Library" } // only stat related in unique
|
||||
val scienceBuilding = buildableNotWonders.asSequence()
|
||||
.filter { it.isStatRelated(Stat.Science) || it.name=="Library" } // only stat related in unique
|
||||
.minBy { it.cost }
|
||||
if (scienceBuilding != null) {
|
||||
var modifier = 1.1f
|
||||
@ -233,7 +237,7 @@ class ConstructionAutomation(val cityConstructions: CityConstructions){
|
||||
}
|
||||
|
||||
private fun addGoldBuildingChoice() {
|
||||
val goldBuilding = buildableNotWonders.filter { it.isStatRelated(Stat.Gold) }
|
||||
val goldBuilding = buildableNotWonders.asSequence().filter { it.isStatRelated(Stat.Gold) }
|
||||
.minBy { it.cost }
|
||||
if (goldBuilding != null) {
|
||||
val modifier = if (civInfo.statsForNextTurn.gold < 0) 3f else 1.2f
|
||||
@ -244,7 +248,7 @@ class ConstructionAutomation(val cityConstructions: CityConstructions){
|
||||
private fun addProductionBuildingChoice() {
|
||||
val hasWaterResource = cityInfo.tilesInRange
|
||||
.any { it.isWater && it.resource!=null && it.position in cityInfo.tiles }
|
||||
val productionBuilding = buildableNotWonders
|
||||
val productionBuilding = buildableNotWonders.asSequence()
|
||||
.filter { it.isStatRelated(Stat.Production)
|
||||
|| (hasWaterResource && (it.uniques.contains("+1 production and gold from all sea resources worked by the city")
|
||||
|| it.uniques.contains("+1 production from all sea resources worked by the city")) )
|
||||
@ -256,7 +260,7 @@ class ConstructionAutomation(val cityConstructions: CityConstructions){
|
||||
}
|
||||
|
||||
private fun addFoodBuildingChoice() {
|
||||
val foodBuilding = buildableNotWonders.filter { it.isStatRelated(Stat.Food)
|
||||
val foodBuilding = buildableNotWonders.asSequence().filter { it.isStatRelated(Stat.Food)
|
||||
|| it.getBaseBuilding(civInfo.gameInfo.ruleSet).name == "Aqueduct" || it.getBaseBuilding(civInfo.gameInfo.ruleSet).name == "Medical Lab"} // only stat related in unique
|
||||
.minBy { it.cost }
|
||||
if (foodBuilding != null) {
|
||||
|
@ -19,7 +19,7 @@ class SpecificUnitAutomation{
|
||||
}
|
||||
|
||||
fun automateWorkBoats(unit: MapUnit) {
|
||||
val seaResourcesInCities = unit.civInfo.cities.flatMap { city -> city.getWorkableTiles() }
|
||||
val seaResourcesInCities = unit.civInfo.cities.asSequence().flatMap { city -> city.getWorkableTiles() }
|
||||
.filter { hasWorkableSeaResource(it, unit.civInfo) && (unit.movement.canMoveTo(it) || unit.currentTile == it) }
|
||||
val closestReachableResource = seaResourcesInCities.sortedBy { it.arialDistanceTo(unit.currentTile) }
|
||||
.firstOrNull { unit.movement.canReach(it) }
|
||||
|
@ -6,8 +6,8 @@ import com.unciv.logic.automation.ConstructionAutomation
|
||||
import com.unciv.logic.civilization.AlertType
|
||||
import com.unciv.logic.civilization.PopupAlert
|
||||
import com.unciv.models.ruleset.Building
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.models.stats.Stats
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.utils.withItem
|
||||
import com.unciv.ui.utils.withoutItem
|
||||
import java.util.*
|
||||
@ -33,11 +33,11 @@ class CityConstructions {
|
||||
return toReturn
|
||||
}
|
||||
|
||||
internal fun getBuildableBuildings(): List<Building> = cityInfo.getRuleset().buildings.values
|
||||
.filter { it.isBuildable(this) }
|
||||
internal fun getBuildableBuildings(): Sequence<Building> = cityInfo.getRuleset().buildings.values
|
||||
.asSequence().filter { it.isBuildable(this) }
|
||||
|
||||
fun getConstructableUnits() = cityInfo.getRuleset().units.values
|
||||
.filter { it.isBuildable(this) }
|
||||
.asSequence().filter { it.isBuildable(this) }
|
||||
|
||||
fun getStats(): Stats {
|
||||
val stats = Stats()
|
||||
@ -109,7 +109,7 @@ class CityConstructions {
|
||||
throw NotBuildingOrUnitException("$constructionName is not a building or a unit!")
|
||||
}
|
||||
|
||||
internal fun getBuiltBuildings(): List<Building> = builtBuildingObjects
|
||||
internal fun getBuiltBuildings(): Sequence<Building> = builtBuildingObjects.asSequence()
|
||||
|
||||
fun containsBuildingOrEquivalent(building: String): Boolean =
|
||||
isBuilt(building) || getBuiltBuildings().any{it.replaces==building}
|
||||
|
@ -116,7 +116,7 @@ class CityInfo {
|
||||
|
||||
|
||||
fun getCenterTile(): TileInfo = centerTileInfo
|
||||
fun getTiles(): List<TileInfo> = tiles.map { tileMap[it] }
|
||||
fun getTiles(): Sequence<TileInfo> = tiles.asSequence().map { tileMap[it] }
|
||||
fun getWorkableTiles() = getTiles().filter { it in tilesInRange }
|
||||
|
||||
fun isCapital() = cityConstructions.isBuilt("Palace")
|
||||
@ -192,7 +192,7 @@ class CityInfo {
|
||||
return 0
|
||||
}
|
||||
|
||||
fun getBuildingUniques(): List<String> = cityConstructions.getBuiltBuildings().flatMap { it.uniques }
|
||||
fun getBuildingUniques(): Sequence<String> = cityConstructions.getBuiltBuildings().flatMap { it.uniques.asSequence() }
|
||||
fun containsBuildingUnique(unique:String) = cityConstructions.getBuiltBuildings().any { it.uniques.contains(unique) }
|
||||
|
||||
fun getGreatPersonMap():HashMap<String,Stats>{
|
||||
|
@ -492,7 +492,7 @@ class CivilizationInfo {
|
||||
val city = NextTurnAutomation().getClosestCities(this, otherCiv).city1
|
||||
val militaryUnit = city.cityConstructions.getConstructableUnits()
|
||||
.filter { !it.unitType.isCivilian() && it.unitType.isLandUnit() }
|
||||
.random()
|
||||
.toList().random()
|
||||
placeUnitNearTile(city.location, militaryUnit.name)
|
||||
addNotification("[${otherCiv.civName}] gave us a [${militaryUnit.name}] as gift near [${city.name}]!", null, Color.GREEN)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user