mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-27 22:06:05 -04:00
performance: Cache uniques for calculating specialist stats
This commit is contained in:
parent
9c121086ea
commit
ad299a8a62
@ -26,8 +26,8 @@ object Automation {
|
||||
return rankStatsForCityWork(stats, city, cityStats)
|
||||
}
|
||||
|
||||
fun rankSpecialist(specialist: String, city: City, cityStats: Stats): Float {
|
||||
val stats = city.cityStats.getStatsOfSpecialist(specialist)
|
||||
fun rankSpecialist(specialist: String, city: City, cityStats: Stats, localUniqueCache: LocalUniqueCache): Float {
|
||||
val stats = city.cityStats.getStatsOfSpecialist(specialist, localUniqueCache)
|
||||
var rank = rankStatsForCityWork(stats, city, cityStats, true)
|
||||
// derive GPP score
|
||||
var gpp = 0f
|
||||
@ -337,10 +337,11 @@ object Automation {
|
||||
|
||||
/** Support [UniqueType.CreatesOneImprovement] unique - find best tile for placement automation */
|
||||
fun getTileForConstructionImprovement(city: City, improvement: TileImprovement): Tile? {
|
||||
val localUniqueCache = LocalUniqueCache()
|
||||
return city.getTiles().filter {
|
||||
it.improvementFunctions.canBuildImprovement(improvement, city.civ)
|
||||
}.maxByOrNull {
|
||||
rankTileForCityWork(it, city, city.cityStats.currentCityStats)
|
||||
rankTileForCityWork(it, city, city.cityStats.currentCityStats, localUniqueCache)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -178,14 +178,14 @@ class CityStats(val city: City) {
|
||||
return !city.containsBuildingUnique(UniqueType.RemoveAnnexUnhappiness)
|
||||
}
|
||||
|
||||
fun getStatsOfSpecialist(specialistName: String): Stats {
|
||||
fun getStatsOfSpecialist(specialistName: String, localUniqueCache: LocalUniqueCache = LocalUniqueCache(false)): Stats {
|
||||
val specialist = city.getRuleset().specialists[specialistName]
|
||||
?: return Stats()
|
||||
val stats = specialist.cloneStats()
|
||||
for (unique in city.getMatchingUniques(UniqueType.StatsFromSpecialist))
|
||||
for (unique in localUniqueCache.get(UniqueType.StatsFromSpecialist.name, city.getMatchingUniques(UniqueType.StatsFromSpecialist)))
|
||||
if (city.matchesFilter(unique.params[1]))
|
||||
stats.add(unique.stats)
|
||||
for (unique in city.civ.getMatchingUniques(UniqueType.StatsFromObject))
|
||||
for (unique in localUniqueCache.get(UniqueType.StatsFromObject.name, city.civ.getMatchingUniques(UniqueType.StatsFromObject)))
|
||||
if (unique.params[1] == specialistName)
|
||||
stats.add(unique.stats)
|
||||
return stats
|
||||
@ -193,8 +193,9 @@ class CityStats(val city: City) {
|
||||
|
||||
private fun getStatsFromSpecialists(specialists: Counter<String>): Stats {
|
||||
val stats = Stats()
|
||||
val localUniqueCache = LocalUniqueCache()
|
||||
for (entry in specialists.filter { it.value > 0 })
|
||||
stats.add(getStatsOfSpecialist(entry.key) * entry.value)
|
||||
stats.add(getStatsOfSpecialist(entry.key, localUniqueCache) * entry.value)
|
||||
return stats
|
||||
}
|
||||
|
||||
|
@ -168,11 +168,11 @@ class CityPopulationManager : IsPartOfGameInfoSerialization {
|
||||
val bestJob: String? = if (city.manualSpecialists) null else getMaxSpecialists()
|
||||
.filter { specialistAllocations[it.key]!! < it.value }
|
||||
.map { it.key }
|
||||
.maxByOrNull { Automation.rankSpecialist(it, city, cityStats) }
|
||||
.maxByOrNull { Automation.rankSpecialist(it, city, cityStats, localUniqueCache) }
|
||||
|
||||
var valueBestSpecialist = 0f
|
||||
if (bestJob != null) {
|
||||
valueBestSpecialist = Automation.rankSpecialist(bestJob, city, cityStats)
|
||||
valueBestSpecialist = Automation.rankSpecialist(bestJob, city, cityStats, localUniqueCache)
|
||||
}
|
||||
|
||||
//assign population
|
||||
@ -208,7 +208,7 @@ class CityPopulationManager : IsPartOfGameInfoSerialization {
|
||||
if (amount > maxSpecialists[specialistName]!!)
|
||||
specialistAllocations[specialistName] = maxSpecialists[specialistName]!!
|
||||
|
||||
|
||||
val localUniqueCache = LocalUniqueCache()
|
||||
|
||||
while (getFreePopulation() < 0) {
|
||||
//evaluate tiles
|
||||
@ -217,19 +217,19 @@ class CityPopulationManager : IsPartOfGameInfoSerialization {
|
||||
city.workedTiles.asSequence()
|
||||
.map { city.tileMap[it] }
|
||||
.minByOrNull {
|
||||
Automation.rankTileForCityWork(it, city, city.cityStats.currentCityStats)
|
||||
Automation.rankTileForCityWork(it, city, city.cityStats.currentCityStats, localUniqueCache)
|
||||
+(if (it.isLocked()) 10 else 0)
|
||||
}!!
|
||||
}
|
||||
val valueWorstTile = if (worstWorkedTile == null) 0f
|
||||
else Automation.rankTileForCityWork(worstWorkedTile, city, city.cityStats.currentCityStats)
|
||||
else Automation.rankTileForCityWork(worstWorkedTile, city, city.cityStats.currentCityStats, localUniqueCache)
|
||||
|
||||
//evaluate specialists
|
||||
val worstAutoJob: String? = if (city.manualSpecialists) null else specialistAllocations.keys
|
||||
.minByOrNull { Automation.rankSpecialist(it, city, city.cityStats.currentCityStats) }
|
||||
.minByOrNull { Automation.rankSpecialist(it, city, city.cityStats.currentCityStats, localUniqueCache) }
|
||||
var valueWorstSpecialist = 0f
|
||||
if (worstAutoJob != null)
|
||||
valueWorstSpecialist = Automation.rankSpecialist(worstAutoJob, city, city.cityStats.currentCityStats)
|
||||
valueWorstSpecialist = Automation.rankSpecialist(worstAutoJob, city, city.cityStats.currentCityStats, localUniqueCache)
|
||||
|
||||
|
||||
// un-assign population
|
||||
@ -249,7 +249,7 @@ class CityPopulationManager : IsPartOfGameInfoSerialization {
|
||||
// and population goes below the number of specialists, e.g. city is razing.
|
||||
// Let's give a chance to do the work automatically at least.
|
||||
val worstJob = specialistAllocations.keys.minByOrNull {
|
||||
Automation.rankSpecialist(it, city, city.cityStats.currentCityStats) }
|
||||
Automation.rankSpecialist(it, city, city.cityStats.currentCityStats, localUniqueCache) }
|
||||
?: break // sorry, we can do nothing about that
|
||||
specialistAllocations.add(worstJob, -1)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user