Resolved #1422 - resources are now spread over different terrains as much as possible

This commit is contained in:
Yair Morgenstern 2019-12-08 21:19:45 +02:00
parent 026afb2c88
commit b6bb961d7c
3 changed files with 21 additions and 6 deletions

View file

Before

Width:  |  Height:  |  Size: 780 B

After

Width:  |  Height:  |  Size: 780 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

View file

@ -9,6 +9,7 @@ import com.unciv.models.gamebasics.tile.ResourceType
import com.unciv.models.gamebasics.tile.TerrainType import com.unciv.models.gamebasics.tile.TerrainType
import com.unciv.models.metadata.GameParameters import com.unciv.models.metadata.GameParameters
import java.util.* import java.util.*
import kotlin.collections.HashMap
import kotlin.math.* import kotlin.math.*
// This is no longer an Enum because there were map types that were disabled, // This is no longer an Enum because there were map types that were disabled,
@ -205,13 +206,13 @@ class MapGenerator {
if (tile.resource != null) if (tile.resource != null)
tile.resource = null tile.resource = null
randomizeStrategicResources(mapToReturn, distance, ruleset) spreadStrategicResources(mapToReturn, distance, ruleset)
randomizeResource(mapToReturn, distance, ResourceType.Luxury, ruleset) spreadResource(mapToReturn, distance, ResourceType.Luxury, ruleset)
randomizeResource(mapToReturn, distance, ResourceType.Bonus, ruleset) spreadResource(mapToReturn, distance, ResourceType.Bonus, ruleset)
} }
// Here, we need each specific resource to be spread over the map - it matters less if specific resources are near each other // Here, we need each specific resource to be spread over the map - it matters less if specific resources are near each other
private fun randomizeStrategicResources(mapToReturn: TileMap, distance: Int, ruleset: Ruleset) { private fun spreadStrategicResources(mapToReturn: TileMap, distance: Int, ruleset: Ruleset) {
val resourcesOfType = ruleset.TileResources.values.filter { it.resourceType == ResourceType.Strategic } val resourcesOfType = ruleset.TileResources.values.filter { it.resourceType == ResourceType.Strategic }
for (resource in resourcesOfType) { for (resource in resourcesOfType) {
val suitableTiles = mapToReturn.values val suitableTiles = mapToReturn.values
@ -227,7 +228,7 @@ class MapGenerator {
} }
// Here, we need there to be some luxury/bonus resource - it matters less what // Here, we need there to be some luxury/bonus resource - it matters less what
private fun randomizeResource(mapToReturn: TileMap, distance: Int, resourceType: ResourceType, ruleset: Ruleset) { private fun spreadResource(mapToReturn: TileMap, distance: Int, resourceType: ResourceType, ruleset: Ruleset) {
val resourcesOfType = ruleset.TileResources.values.filter { it.resourceType == resourceType } val resourcesOfType = ruleset.TileResources.values.filter { it.resourceType == resourceType }
val suitableTiles = mapToReturn.values val suitableTiles = mapToReturn.values
@ -254,11 +255,25 @@ class MapGenerator {
var availableTiles = suitableTiles.toList() var availableTiles = suitableTiles.toList()
val chosenTiles = ArrayList<TileInfo>() val chosenTiles = ArrayList<TileInfo>()
// If possible, we want to equalize the base terrains upon which
// the resources are found, so we save how many have been
// found for each base terrain and try to get one from the lowerst
val baseTerrainsToChosenTiles = HashMap<String,Int>()
for(tileInfo in availableTiles){
if(tileInfo.baseTerrain !in baseTerrainsToChosenTiles)
baseTerrainsToChosenTiles.put(tileInfo.baseTerrain,0)
}
for (i in 1..numberOfResources) { for (i in 1..numberOfResources) {
if (availableTiles.isEmpty()) break if (availableTiles.isEmpty()) break
val chosenTile = availableTiles.random() val orderedKeys = baseTerrainsToChosenTiles.entries
.sortedBy { it.value }.map { it.key }
val firstKeyWithTilesLeft = orderedKeys
.first { availableTiles.any { tile -> tile.baseTerrain== it} }
val chosenTile = availableTiles.filter { it.baseTerrain==firstKeyWithTilesLeft }.random()
availableTiles = availableTiles.filter { it.arialDistanceTo(chosenTile) > distanceBetweenResources } availableTiles = availableTiles.filter { it.arialDistanceTo(chosenTile) > distanceBetweenResources }
chosenTiles.add(chosenTile) chosenTiles.add(chosenTile)
baseTerrainsToChosenTiles[firstKeyWithTilesLeft] = baseTerrainsToChosenTiles[firstKeyWithTilesLeft]!!+1
} }
// Either we got them all, or we're not going to get anything better // Either we got them all, or we're not going to get anything better
if (chosenTiles.size == numberOfResources || distanceBetweenResources == 1) return chosenTiles if (chosenTiles.size == numberOfResources || distanceBetweenResources == 1) return chosenTiles