From 417831085b620236c93fa8854d036cfa277834a3 Mon Sep 17 00:00:00 2001 From: Yair Morgenstern Date: Sat, 7 May 2022 22:43:34 +0300 Subject: [PATCH] Resolved ANR in City Screen by increasing performance of rankTileForExpansion --- core/src/com/unciv/logic/automation/Automation.kt | 6 ++++-- .../src/com/unciv/logic/city/CityExpansionManager.kt | 12 +++++++----- core/src/com/unciv/ui/cityscreen/CityStatsTable.kt | 2 +- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/core/src/com/unciv/logic/automation/Automation.kt b/core/src/com/unciv/logic/automation/Automation.kt index 3e40313323..9a450337c2 100644 --- a/core/src/com/unciv/logic/automation/Automation.kt +++ b/core/src/com/unciv/logic/automation/Automation.kt @@ -12,6 +12,7 @@ import com.unciv.models.ruleset.MilestoneType import com.unciv.models.ruleset.Victory import com.unciv.models.ruleset.Victory.Focus import com.unciv.models.ruleset.tile.ResourceType +import com.unciv.models.ruleset.unique.LocalUniqueCache import com.unciv.models.ruleset.unique.UniqueType import com.unciv.models.ruleset.unit.BaseUnit import com.unciv.models.stats.Stats @@ -271,7 +272,8 @@ object Automation { } // Ranks a tile for the expansion algorithm of cities - internal fun rankTileForExpansion(tile: TileInfo, cityInfo: CityInfo): Int { + internal fun rankTileForExpansion(tile: TileInfo, cityInfo: CityInfo, + localUniqueCache: LocalUniqueCache = LocalUniqueCache(false)): Int { // https://github.com/Gedemon/Civ5-DLL/blob/aa29e80751f541ae04858b6d2a2c7dcca454201e/CvGameCoreDLL_Expansion1/CvCity.cpp#L10301 // Apparently this is not the full calculation. The exact tiles are also // dependent on which tiles are between the chosen tile and the city center @@ -302,7 +304,7 @@ object Automation { if (tile.naturalWonder != null) score -= 105 // Straight up take the sum of all yields - score -= tile.getTileStats(cityInfo, cityInfo.civInfo).values.sum().toInt() + score -= tile.getTileStats(cityInfo, cityInfo.civInfo, localUniqueCache).values.sum().toInt() // Check if we get access to better tiles from this tile var adjacentNaturalWonder = false diff --git a/core/src/com/unciv/logic/city/CityExpansionManager.kt b/core/src/com/unciv/logic/city/CityExpansionManager.kt index ecba8184b7..34b196b27d 100644 --- a/core/src/com/unciv/logic/city/CityExpansionManager.kt +++ b/core/src/com/unciv/logic/city/CityExpansionManager.kt @@ -5,6 +5,7 @@ import com.unciv.logic.automation.Automation import com.unciv.logic.civilization.LocationAction import com.unciv.logic.civilization.NotificationIcon import com.unciv.logic.map.TileInfo +import com.unciv.models.ruleset.unique.LocalUniqueCache import com.unciv.models.ruleset.unique.UniqueType import com.unciv.ui.utils.toPercent import com.unciv.ui.utils.withItem @@ -72,17 +73,18 @@ class CityExpansionManager { return cost.roundToInt() } + fun getChoosableTiles() = cityInfo.getCenterTile().getTilesInDistance(5) + .filter { it.getOwner() == null } + fun chooseNewTileToOwn(): TileInfo? { - val choosableTiles = cityInfo.getCenterTile().getTilesInDistance(5) - .filter { it.getOwner() == null } - // Technically, in the original a random tile with the lowest score was selected // However, doing this requires either caching it, which is way more work, // or selecting all possible tiles and only choosing one when the border expands. // But since the order in which tiles are selected in distance is kinda random anyways, // this is fine. - return choosableTiles.minByOrNull { - Automation.rankTileForExpansion(it, cityInfo) + val localUniqueCache = LocalUniqueCache() + return getChoosableTiles().minByOrNull { + Automation.rankTileForExpansion(it, cityInfo, localUniqueCache) } } diff --git a/core/src/com/unciv/ui/cityscreen/CityStatsTable.kt b/core/src/com/unciv/ui/cityscreen/CityStatsTable.kt index 23e023a95b..bd6fc7a586 100644 --- a/core/src/com/unciv/ui/cityscreen/CityStatsTable.kt +++ b/core/src/com/unciv/ui/cityscreen/CityStatsTable.kt @@ -59,7 +59,7 @@ class CityStatsTable(val cityScreen: CityScreen): Table() { cityInfo.population.getFreePopulation().toString() + "/" + cityInfo.population.population var turnsToExpansionString = - if (cityInfo.cityStats.currentCityStats.culture > 0 && cityInfo.expansion.chooseNewTileToOwn() != null) { + if (cityInfo.cityStats.currentCityStats.culture > 0 && cityInfo.expansion.getChoosableTiles().any()) { val remainingCulture = cityInfo.expansion.getCultureToNextTile() - cityInfo.expansion.cultureStored var turnsToExpansion = ceil(remainingCulture / cityInfo.cityStats.currentCityStats.culture).toInt() if (turnsToExpansion < 1) turnsToExpansion = 1