From f75ce00d83ddd301683f23297a970bf493aa2592 Mon Sep 17 00:00:00 2001 From: WhoIsJohannes Date: Thu, 27 Apr 2023 15:35:25 +0200 Subject: [PATCH] Cache getDistanceToTilesWithinTurn by removing tilesToIgnore from the call and doing that filtering later. Also simplify caller side with some transformations around differences for the first iteration and subsequent iterations. --- .../unciv/logic/map/mapunit/UnitMovement.kt | 32 ++++++++----------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/core/src/com/unciv/logic/map/mapunit/UnitMovement.kt b/core/src/com/unciv/logic/map/mapunit/UnitMovement.kt index 356515b522..c415ea1bc5 100644 --- a/core/src/com/unciv/logic/map/mapunit/UnitMovement.kt +++ b/core/src/com/unciv/logic/map/mapunit/UnitMovement.kt @@ -157,7 +157,6 @@ class UnitMovement(val unit: MapUnit) { origin: Vector2, unitMovement: Float, considerZoneOfControl: Boolean = true, - tilesToIgnore: HashSet? = null, passThroughCache: HashMap = HashMap(), movementCostCache: HashMap, Float> = HashMap() ): PathsToTilesWithinTurn { @@ -174,7 +173,6 @@ class UnitMovement(val unit: MapUnit) { val updatedTiles = ArrayList() for (tileToCheck in tilesToCheck) for (neighbor in tileToCheck.neighbors) { - if (tilesToIgnore?.contains(neighbor) == true) continue // ignore this tile var totalDistanceToTile: Float = when { !unit.civ.hasExplored(neighbor) -> distanceToTiles[tileToCheck]!!.totalDistance + 1f // If we don't know then we just guess it to be 1. @@ -243,44 +241,41 @@ class UnitMovement(val unit: MapUnit) { val movementTreeParents = HashMap() // contains a map of "you can get from X to Y in that turn" movementTreeParents[currentTile] = null - var movementThisTurn = unit.currentMovement var distance = 1 val newTilesToCheck = ArrayList() - var considerZoneOfControl = true // only for first distance! val visitedTiles: HashSet = hashSetOf(currentTile) val civilization = unit.civ + val unitMaxMovement = unit.getMaxMovement().toFloat() val passThroughCache = HashMap() val movementCostCache = HashMap, Float>() val canMoveToCache = HashMap() + val distanceToTilesWithinTurnCache = HashMap() while (true) { - if (distance == 2) { // only set this once after distance > 1 - movementThisTurn = unit.getMaxMovement().toFloat() - considerZoneOfControl = false // by then units would have moved around, we don't need to consider untenable futures when it harms performance! - } newTilesToCheck.clear() var tilesByPreference = tilesToCheck.sortedBy { it.aerialDistanceTo(destination) } // Avoid embarkation when possible if (unit.type.isLandUnit()) tilesByPreference = tilesByPreference.sortedByDescending { it.isLand } - for (tileToCheck in tilesByPreference) { val distanceToTilesThisTurn = if (distance == 1) { - getDistanceToTiles(considerZoneOfControl, passThroughCache, movementCostCache) // check cache + getDistanceToTiles(true, passThroughCache, movementCostCache) // check cache } else { - getDistanceToTilesWithinTurn( - tileToCheck.position, - movementThisTurn, - considerZoneOfControl, - visitedTiles, - passThroughCache, - movementCostCache - ) + distanceToTilesWithinTurnCache.getOrPut(tileToCheck.position) { + getDistanceToTilesWithinTurn( + tileToCheck.position, + unitMaxMovement, + false, + passThroughCache, + movementCostCache + ) + } } for (reachableTile in distanceToTilesThisTurn.keys) { + if (visitedTiles.contains(reachableTile)) continue // Avoid damaging terrain on first pass if (avoidDamagingTerrain && unit.getDamageFromTerrain(reachableTile) > 0) continue @@ -788,7 +783,6 @@ class UnitMovement(val unit: MapUnit) { unit.currentTile.position, unit.currentMovement, considerZoneOfControl, - null, passThroughCache, movementCostCache )