diff --git a/core/src/com/unciv/logic/HexMath.kt b/core/src/com/unciv/logic/HexMath.kt index 04be602a7b..a9a65b2c91 100644 --- a/core/src/com/unciv/logic/HexMath.kt +++ b/core/src/com/unciv/logic/HexMath.kt @@ -74,8 +74,12 @@ class HexMath { return hexesToReturn } - fun getDistance(origin: Vector2, destination: Vector2): Int { // Yes, this is a dumb implementation. But I can't be arsed to think of a better one right now, other stuff to do. - return max(abs(origin.x-destination.x),abs(origin.y-destination.y) ).toInt() + fun getDistance(origin: Vector2, destination: Vector2): Int { + val relative_x = origin.x-destination.x + val relative_y = origin.y-destination.y + if (relative_x * relative_y >= 0) + return max(abs(relative_x),abs(relative_y)).toInt() + else + return (abs(relative_x) + abs(relative_y)).toInt() } - } diff --git a/core/src/com/unciv/logic/map/RandomMapGenerator.kt b/core/src/com/unciv/logic/map/RandomMapGenerator.kt index b7d49b003e..345fd98941 100644 --- a/core/src/com/unciv/logic/map/RandomMapGenerator.kt +++ b/core/src/com/unciv/logic/map/RandomMapGenerator.kt @@ -11,6 +11,79 @@ import java.util.* import kotlin.collections.HashMap import kotlin.math.ceil +class CelluarAutomataRandomMapGenerator:SeedRandomMapGenerator() { + internal val landProb = 0.55f + internal val numSmooth = 4 + + override fun generateMap(distance: Int): HashMap { + val mapVectors = HexMath().getVectorsInDistance(Vector2.Zero, distance) + val landscape = HashMap() + + //init + for (vector in mapVectors) + landscape[vector] = generateInitTerrain(vector, distance) + + //smooth + for (loop in 0..numSmooth) { + for (vector in mapVectors) { + if (HexMath().getDistance(Vector2.Zero, vector) < distance) { + val neighborLands = HexMath().getAdjacentVectors(vector).count {landscape[it] == TerrainType.Land} + if (landscape[vector] == TerrainType.Land) { + if (neighborLands < 3) + landscape[vector] = TerrainType.Water + } else { + if (neighborLands > 3) + landscape[vector] = TerrainType.Land + } + } + else { + landscape[vector] = TerrainType.Water + } + } + } + + val map = HashMap() + for (vector in mapVectors) + map[vector] = generateTile(vector,landscape[vector]!!) + + divideIntoAreas(6, 0f, map) + + val mapToReturn = HashMap() + for(tile in map) { + tile.value.setTransients() + mapToReturn[tile.key.toString()] = tile.value + } + + setWaterTiles(mapToReturn) + + for(tile in mapToReturn.values) randomizeTile(tile,mapToReturn) + + return mapToReturn + } + + private fun generateInitTerrain(vector: Vector2, distance: Int): TerrainType { + var type = TerrainType.Land + if (HexMath().getDistance(Vector2.Zero, vector) > 0.9f * distance) + type = if (Random().nextDouble() < 0.1) TerrainType.Land else TerrainType.Water + else if (HexMath().getDistance(Vector2.Zero, vector) > 0.85f * distance) + type = if (Random().nextDouble() < 0.2) TerrainType.Land else TerrainType.Water + else + type = if (Random().nextDouble() < landProb) TerrainType.Land else TerrainType.Water + return type + } + + private fun generateTile(vector: Vector2, type: TerrainType): TileInfo { + val tile=TileInfo() + tile.position=vector + if (type == TerrainType.Land) + tile.baseTerrain = "" + else + tile.baseTerrain = "Ocean" + return tile + } +} + + class PerlinNoiseRandomMapGenerator:SeedRandomMapGenerator(){ override fun generateMap(distance: Int): HashMap { val map = HashMap() diff --git a/core/src/com/unciv/logic/map/TileMap.kt b/core/src/com/unciv/logic/map/TileMap.kt index 8eb3bbd966..2628fcdff0 100644 --- a/core/src/com/unciv/logic/map/TileMap.kt +++ b/core/src/com/unciv/logic/map/TileMap.kt @@ -35,7 +35,7 @@ class TileMap { val map:HashMap if(mapType==NewGameScreen.NewGameParameters.MapType.WithWater) - map = PerlinNoiseRandomMapGenerator().generateMap(distance) + map = CelluarAutomataRandomMapGenerator().generateMap(distance) else map = SeedRandomMapGenerator().generateMap(distance,0f)