From dbc6bc9f30efffeab4bb546dc4186f2e6a21e1bf Mon Sep 17 00:00:00 2001 From: SimonCeder <63475501+SimonCeder@users.noreply.github.com> Date: Sat, 24 Jul 2021 21:19:46 +0200 Subject: [PATCH] optimizing the spawn placement algorithm (#4620) * optimize spawn placement * consistent nomenclature --- core/src/com/unciv/logic/GameStarter.kt | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/core/src/com/unciv/logic/GameStarter.kt b/core/src/com/unciv/logic/GameStarter.kt index 5b18aa7208..3ec6698a3b 100644 --- a/core/src/com/unciv/logic/GameStarter.kt +++ b/core/src/com/unciv/logic/GameStarter.kt @@ -16,6 +16,7 @@ import com.unciv.ui.newgamescreen.GameSetupInfo import java.util.* import kotlin.NoSuchElementException import kotlin.collections.ArrayList +import kotlin.collections.HashMap import kotlin.math.max object GameStarter { @@ -182,6 +183,11 @@ object GameStarter { var startingUnits: MutableList var eraUnitReplacement: String + val startScores = HashMap() + for (tile in gameInfo.tileMap.values) { + startScores[tile] = tile.getTileStartScore() + } + // First we get start locations for the major civs, on the second pass the city states (without predetermined starts) can squeeze in wherever // I hear copying code is good val cityStatesWithStartingLocations = @@ -189,7 +195,7 @@ object GameStarter { .filter { it.improvement != null && it.improvement!!.startsWith("StartingLocation ") } .map { it.improvement!!.replace("StartingLocation ", "") } val bestCivs = gameInfo.civilizations.filter { !it.isBarbarian() && (!it.isCityState() || it.civName in cityStatesWithStartingLocations) } - val bestLocations = getStartingLocations(bestCivs, gameInfo.tileMap) + val bestLocations = getStartingLocations(bestCivs, gameInfo.tileMap, startScores) for (civ in bestCivs) { if (civ.isCityState()) // Already have explicit starting locations @@ -201,7 +207,7 @@ object GameStarter { val startingLocations = getStartingLocations( gameInfo.civilizations.filter { !it.isBarbarian() }, - gameInfo.tileMap) + gameInfo.tileMap, startScores) val settlerLikeUnits = ruleSet.units.filter { it.value.uniqueObjects.any { it.placeholderText == Constants.settlerUnique } @@ -211,7 +217,7 @@ object GameStarter { for (civ in gameInfo.civilizations.filter { !it.isBarbarian() && !it.isSpectator() }) { val startingLocation = startingLocations[civ]!! - if(civ.isMajorCiv() && startingLocation.getTileStartScore() < 45) { + if(civ.isMajorCiv() && startScores[startingLocation]!! < 45) { // An unusually bad spawning location addConsolationPrize(gameInfo, startingLocation, 45 - startingLocation.getTileStartScore().toInt()) } @@ -304,7 +310,7 @@ object GameStarter { } } - private fun getStartingLocations(civs: List, tileMap: TileMap): HashMap { + private fun getStartingLocations(civs: List, tileMap: TileMap, startScores: HashMap): HashMap { var landTiles = tileMap.values // Games starting on snow might as well start over... .filter { it.isLand && !it.isImpassible() && it.baseTerrain != Constants.snow } @@ -350,7 +356,7 @@ object GameStarter { if (civ.isCityState()) distanceToNext = minimumDistanceBetweenStartingLocations / 2 // We allow random city states to squeeze in tighter - freeTiles.sortBy { it.getTileStartScore() } + freeTiles.sortBy { startScores[it] } var preferredTiles = freeTiles.toList()