mirror of
https://github.com/yairm210/Unciv.git
synced 2025-01-03 21:40:31 +07:00
Performance: Cache uniques when choosing best tiles to settle/create improvements on
Resuse cache between cities for choosing best improvement for worker to pick (but not between workers...YET) Alternate title: MOAR CACHES EVERYWHERE
This commit is contained in:
parent
f8ccefd10c
commit
ad7397ecc9
@ -362,11 +362,12 @@ object Automation {
|
||||
}
|
||||
|
||||
// Ranks a tile for any purpose except the expansion algorithm of cities
|
||||
internal fun rankTile(tile: Tile?, civInfo: Civilization): Float {
|
||||
internal fun rankTile(tile: Tile?, civInfo: Civilization,
|
||||
localUniqueCache: LocalUniqueCache): Float {
|
||||
if (tile == null) return 0f
|
||||
val tileOwner = tile.getOwner()
|
||||
if (tileOwner != null && tileOwner != civInfo) return 0f // Already belongs to another civilization, useless to us
|
||||
val stats = tile.stats.getTileStats(null, civInfo)
|
||||
val stats = tile.stats.getTileStats(null, civInfo, localUniqueCache)
|
||||
var rank = rankStatsValue(stats, civInfo)
|
||||
if (tile.improvement == null) rank += 0.5f // improvement potential!
|
||||
if (tile.isPillaged()) rank += 0.6f
|
||||
|
@ -7,6 +7,7 @@ import com.unciv.logic.map.mapunit.MapUnit
|
||||
import com.unciv.logic.map.tile.Tile
|
||||
import com.unciv.models.ruleset.tile.ResourceType
|
||||
import com.unciv.models.ruleset.tile.TileResource
|
||||
import com.unciv.models.ruleset.unique.LocalUniqueCache
|
||||
|
||||
object CityLocationTileRanker {
|
||||
fun getBestTilesToFoundCity(unit: MapUnit): Sequence<Pair<Tile, Float>> {
|
||||
@ -93,14 +94,15 @@ object CityLocationTileRanker {
|
||||
tile: Tile,
|
||||
civ: Civilization
|
||||
): Map<Tile, Float> {
|
||||
val uniqueCache = LocalUniqueCache()
|
||||
return tile.getTilesInDistance(7)
|
||||
.filter { canUseTileForRanking(it, civ) }
|
||||
.associateBy({ it }, { Automation.rankTile(it, civ) })
|
||||
.associateBy({ it }, { Automation.rankTile(it, civ, uniqueCache) })
|
||||
}
|
||||
|
||||
private fun getLuxuryResourcesInCivArea(civ: Civilization): Sequence<TileResource> {
|
||||
return civ.cities.asSequence()
|
||||
.flatMap { it.getTiles().asSequence() }.filter { it.resource != null }
|
||||
.flatMap { it.getTiles() }.filter { it.resource != null }
|
||||
.map { it.tileResource }.filter { it.resourceType == ResourceType.Luxury }
|
||||
.distinct()
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ import com.unciv.logic.map.tile.Tile
|
||||
import com.unciv.models.UnitAction
|
||||
import com.unciv.models.UnitActionType
|
||||
import com.unciv.models.ruleset.Building
|
||||
import com.unciv.models.ruleset.unique.LocalUniqueCache
|
||||
import com.unciv.models.ruleset.unique.UniqueType
|
||||
import com.unciv.models.stats.Stat
|
||||
import com.unciv.ui.screens.worldscreen.unit.actions.UnitActions
|
||||
@ -199,10 +200,12 @@ object SpecificUnitAutomation {
|
||||
}
|
||||
|
||||
// if we got here, we're pretty close, start looking!
|
||||
val localUniqueCache = LocalUniqueCache()
|
||||
val chosenTile = applicableTiles.sortedByDescending {
|
||||
Automation.rankTile(
|
||||
it,
|
||||
unit.civ
|
||||
unit.civ,
|
||||
localUniqueCache
|
||||
)
|
||||
}
|
||||
.firstOrNull { unit.movement.canReach(it) }
|
||||
@ -500,7 +503,7 @@ object SpecificUnitAutomation {
|
||||
val tilesInRange = unit.currentTile.getTilesInDistanceRange(2..unit.getRange())
|
||||
var highestTileNukeValue = 0
|
||||
var tileToNuke: Tile? = null
|
||||
tilesInRange.forEach {
|
||||
tilesInRange.forEach {
|
||||
val value = getNukeLocationValue(unit, it)
|
||||
if (value > highestTileNukeValue) {
|
||||
highestTileNukeValue = value
|
||||
@ -524,15 +527,15 @@ object SpecificUnitAutomation {
|
||||
val tilesInBlastRadius = tile.getTilesInDistance(blastRadius)
|
||||
val civsInBlastRadius = tilesInBlastRadius.mapNotNull { it.getOwner() } +
|
||||
tilesInBlastRadius.mapNotNull { it.getFirstUnit()?.civ }
|
||||
|
||||
|
||||
// Don't nuke if it means we will be declaring war on someone!
|
||||
if (civsInBlastRadius.any { it != civ && !it.isAtWarWith(civ) }) return -100000
|
||||
// If there are no enemies to hit, don't nuke
|
||||
if (!civsInBlastRadius.any { it.isAtWarWith(civ) }) return -100000
|
||||
|
||||
|
||||
// Launching a Nuke uses resources, therefore don't launch it by default
|
||||
var explosionValue = -500
|
||||
|
||||
|
||||
// Returns either ourValue or thierValue depending on if the input Civ matches the Nuke's Civ
|
||||
fun evaluateCivValue(targetCiv: Civilization, ourValue: Int, theirValue: Int): Int {
|
||||
if (targetCiv == civ) // We are nuking something that we own!
|
||||
@ -548,8 +551,8 @@ object SpecificUnitAutomation {
|
||||
explosionValue += evaluateCivValue(targetTile.civilianUnit?.civ!!, -100, 25)
|
||||
}
|
||||
// Never nuke our own Civ, don't nuke single enemy civs as well
|
||||
if (targetTile.isCityCenter()
|
||||
&& !(targetTile.getCity()!!.health <= 50f
|
||||
if (targetTile.isCityCenter()
|
||||
&& !(targetTile.getCity()!!.health <= 50f
|
||||
&& targetTile.neighbors.any {it.militaryUnit?.civ == civ})) // Prefer not to nuke cities that we are about to take
|
||||
explosionValue += evaluateCivValue(targetTile.getCity()?.civ!!, -100000, 250)
|
||||
else if (targetTile.owningCity != null) {
|
||||
|
@ -390,14 +390,10 @@ class WorkerAutomation(
|
||||
}
|
||||
if (potentialTileImprovements.isEmpty()) return null
|
||||
|
||||
val cityUniqueCaches = HashMap<City, LocalUniqueCache>()
|
||||
val localUniqueCache = LocalUniqueCache()
|
||||
fun getImprovementRanking(improvementName: String): Float {
|
||||
val improvement = ruleSet.tileImprovements[improvementName]!!
|
||||
val city = tile.getCity()
|
||||
val cache =
|
||||
if (city == null) LocalUniqueCache(false)
|
||||
else cityUniqueCaches.getOrPut(city) { LocalUniqueCache() }
|
||||
val stats = tile.stats.getStatDiffForImprovement(improvement, civInfo, tile.getCity(), cache)
|
||||
val stats = tile.stats.getStatDiffForImprovement(improvement, civInfo, tile.getCity(), localUniqueCache)
|
||||
return Automation.rankStatsValue(stats, unit.civ)
|
||||
}
|
||||
|
||||
|
@ -169,10 +169,10 @@ class ImprovementPickerScreen(
|
||||
//Warn when the current improvement will increase a stat for the tile,
|
||||
// but the tile is outside of the range (> 3 tiles from city center) that can be
|
||||
// worked by a city's population
|
||||
if (stats.values.any { it > 0f }
|
||||
if (tile.owningCity != null
|
||||
&& !improvement.isRoad()
|
||||
&& stats.values.any { it > 0f }
|
||||
&& !improvement.name.startsWith(Constants.remove)
|
||||
&& !improvement.isRoad()
|
||||
&& tile.owningCity != null
|
||||
&& !tile.owningCity!!.getWorkableTiles().contains(tile)
|
||||
)
|
||||
labelText += "\n" + "Not in city work range".tr()
|
||||
|
Loading…
Reference in New Issue
Block a user