optimizing the spawn placement algorithm (#4620)

* optimize spawn placement

* consistent nomenclature
This commit is contained in:
SimonCeder 2021-07-24 21:19:46 +02:00 committed by GitHub
parent aa3be63492
commit dbc6bc9f30
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -16,6 +16,7 @@ import com.unciv.ui.newgamescreen.GameSetupInfo
import java.util.* import java.util.*
import kotlin.NoSuchElementException import kotlin.NoSuchElementException
import kotlin.collections.ArrayList import kotlin.collections.ArrayList
import kotlin.collections.HashMap
import kotlin.math.max import kotlin.math.max
object GameStarter { object GameStarter {
@ -182,6 +183,11 @@ object GameStarter {
var startingUnits: MutableList<String> var startingUnits: MutableList<String>
var eraUnitReplacement: String var eraUnitReplacement: String
val startScores = HashMap<TileInfo, Float>()
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 // 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 // I hear copying code is good
val cityStatesWithStartingLocations = val cityStatesWithStartingLocations =
@ -189,7 +195,7 @@ object GameStarter {
.filter { it.improvement != null && it.improvement!!.startsWith("StartingLocation ") } .filter { it.improvement != null && it.improvement!!.startsWith("StartingLocation ") }
.map { it.improvement!!.replace("StartingLocation ", "") } .map { it.improvement!!.replace("StartingLocation ", "") }
val bestCivs = gameInfo.civilizations.filter { !it.isBarbarian() && (!it.isCityState() || it.civName in cityStatesWithStartingLocations) } 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) for (civ in bestCivs)
{ {
if (civ.isCityState()) // Already have explicit starting locations if (civ.isCityState()) // Already have explicit starting locations
@ -201,7 +207,7 @@ object GameStarter {
val startingLocations = getStartingLocations( val startingLocations = getStartingLocations(
gameInfo.civilizations.filter { !it.isBarbarian() }, gameInfo.civilizations.filter { !it.isBarbarian() },
gameInfo.tileMap) gameInfo.tileMap, startScores)
val settlerLikeUnits = ruleSet.units.filter { val settlerLikeUnits = ruleSet.units.filter {
it.value.uniqueObjects.any { it.placeholderText == Constants.settlerUnique } it.value.uniqueObjects.any { it.placeholderText == Constants.settlerUnique }
@ -211,7 +217,7 @@ object GameStarter {
for (civ in gameInfo.civilizations.filter { !it.isBarbarian() && !it.isSpectator() }) { for (civ in gameInfo.civilizations.filter { !it.isBarbarian() && !it.isSpectator() }) {
val startingLocation = startingLocations[civ]!! val startingLocation = startingLocations[civ]!!
if(civ.isMajorCiv() && startingLocation.getTileStartScore() < 45) { if(civ.isMajorCiv() && startScores[startingLocation]!! < 45) {
// An unusually bad spawning location // An unusually bad spawning location
addConsolationPrize(gameInfo, startingLocation, 45 - startingLocation.getTileStartScore().toInt()) addConsolationPrize(gameInfo, startingLocation, 45 - startingLocation.getTileStartScore().toInt())
} }
@ -304,7 +310,7 @@ object GameStarter {
} }
} }
private fun getStartingLocations(civs: List<CivilizationInfo>, tileMap: TileMap): HashMap<CivilizationInfo, TileInfo> { private fun getStartingLocations(civs: List<CivilizationInfo>, tileMap: TileMap, startScores: HashMap<TileInfo, Float>): HashMap<CivilizationInfo, TileInfo> {
var landTiles = tileMap.values var landTiles = tileMap.values
// Games starting on snow might as well start over... // Games starting on snow might as well start over...
.filter { it.isLand && !it.isImpassible() && it.baseTerrain != Constants.snow } .filter { it.isLand && !it.isImpassible() && it.baseTerrain != Constants.snow }
@ -350,7 +356,7 @@ object GameStarter {
if (civ.isCityState()) if (civ.isCityState())
distanceToNext = minimumDistanceBetweenStartingLocations / 2 // We allow random city states to squeeze in tighter distanceToNext = minimumDistanceBetweenStartingLocations / 2 // We allow random city states to squeeze in tighter
freeTiles.sortBy { it.getTileStartScore() } freeTiles.sortBy { startScores[it] }
var preferredTiles = freeTiles.toList() var preferredTiles = freeTiles.toList()