Solve continentSizes serialization by removing it (#5403)

This commit is contained in:
SomeTroglodyte 2021-10-05 14:30:32 +02:00 committed by GitHub
parent c9f23b644a
commit 4c6f1ecfb8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 42 additions and 7 deletions

View File

@ -84,7 +84,7 @@ object GameStarter {
if (tileMap.continentSizes.isEmpty()) // Probably saved map without continent data
runAndMeasure("assignContinents") {
tileMap.assignContinents()
tileMap.assignContinents(TileMap.AssignContinentsMode.Ensure)
}
runAndMeasure("addCivStartingUnits") {
@ -353,7 +353,7 @@ object GameStarter {
tileMap: TileMap,
startScores: HashMap<TileInfo, Float>
): Map<TileInfo, Float> {
if (tileMap.continentSizes.isEmpty()) tileMap.assignContinents()
tileMap.assignContinents(TileMap.AssignContinentsMode.Ensure)
// We want to distribute starting locations fairly, and thus not place anybody on a small island
// - unless necessary. Old code would only consider landmasses >= 20 tiles.

View File

@ -33,6 +33,7 @@ object MapSaver {
}
}
fun mapToSavedString(tileMap: TileMap): String {
tileMap.assignContinents(TileMap.AssignContinentsMode.Reassign)
val mapJson = json().toJson(tileMap)
return if (saveZipped) Gzip.zip(mapJson) else mapJson
}

View File

@ -804,5 +804,8 @@ open class TileInfo {
this.continent = continent
}
/** Clear continent ID, for map editor */
fun clearContinent() { continent = -1 }
//endregion
}

View File

@ -34,7 +34,6 @@ class TileMap {
var mapParameters = MapParameters()
private var tileList = ArrayList<TileInfo>()
val continentSizes = HashMap<Int, Int>() // Continent ID, Continent size
/** Structure geared for simple serialization by Gdx.Json (which is a little blind to kotlin collections, especially HashSet)
* @param position [Vector2] of the location
@ -79,6 +78,9 @@ class TileMap {
@Transient
val startingLocationsByNation = HashMap<String,HashSet<TileInfo>>()
@Transient
val continentSizes = HashMap<Int, Int>() // Continent ID, Continent size
//endregion
//region Constructors
@ -124,7 +126,6 @@ class TileMap {
toReturn.startingLocations.clear()
toReturn.startingLocations.ensureCapacity(startingLocations.size)
toReturn.startingLocations.addAll(startingLocations)
toReturn.continentSizes.putAll(continentSizes)
return toReturn
}
@ -347,6 +348,7 @@ class TileMap {
}
fun isWaterMap(): Boolean {
assignContinents(AssignContinentsMode.Ensure)
val bigIslands = continentSizes.count { it.value > 20 }
val players = gameInfo.gameParameters.players.count()
return bigIslands >= players
@ -558,13 +560,41 @@ class TileMap {
startingLocationsByNation.clear()
}
/** Behaviour of [assignContinents] */
enum class AssignContinentsMode { Assign, Reassign, Ensure, Clear }
/** Set a continent id for each tile, so we can quickly see which tiles are connected.
* Can also be called on saved maps.
* @throws Exception when any land tile already has a continent ID
* @param mode As follows:
* [Assign][AssignContinentsMode.Assign] = initial assign, throw if tiles have continents.
* [Reassign][AssignContinentsMode.Reassign] = clear continent data and redo for map editor.
* [Ensure][AssignContinentsMode.Ensure] = regenerate continent sizes from tile data, and if that is empty, Assign.
* @throws Exception when `mode==Assign` and any land tile already has a continent ID
* @return A map of continent sizes (continent ID to tile count)
*/
fun assignContinents() {
fun assignContinents(mode: AssignContinentsMode) {
if (mode == AssignContinentsMode.Clear) {
values.forEach { it.clearContinent() }
continentSizes.clear()
return
}
if (mode == AssignContinentsMode.Ensure) {
if (continentSizes.isNotEmpty()) return
for (tile in values) {
val continent = tile.getContinent()
if (continent == -1) continue
continentSizes[continent] = 1 + (continentSizes[continent] ?: 0)
}
if (continentSizes.isNotEmpty()) return
}
var landTiles = values.filter { it.isLand && !it.isImpassible() }
var currentContinent = 0
continentSizes.clear()
if (mode == AssignContinentsMode.Reassign)
values.forEach { it.clearContinent() }
while (landTiles.any()) {
val bfs = BFS(landTiles.random()) { it.isLand && !it.isImpassible() }

View File

@ -74,7 +74,7 @@ class MapGenerator(val ruleset: Ruleset) {
spawnIce(map)
}
runAndMeasure("assignContinents") {
map.assignContinents()
map.assignContinents(TileMap.AssignContinentsMode.Assign)
}
runAndMeasure("NaturalWonderGenerator") {
NaturalWonderGenerator(ruleset, randomness).spawnNaturalWonders(map)

View File

@ -184,6 +184,7 @@ class TileGroupIcons(val tileGroup: TileGroup) {
// different stacking order of the same nations in the same editing session
val nations = tileInfo.tileMap.startingLocationsByNation.asSequence()
.filter { tileInfo in it.value }
.filter { it.key in tileInfo.tileMap.ruleset!!.nations } // Ignore missing nations
.map { it.key to tileInfo.tileMap.ruleset!!.nations[it.key]!! }
.sortedWith(compareBy({ it.second.isCityState() }, { it.first }))
.toList()