Solve CS placement clustering (#7783)

This commit is contained in:
Yair Morgenstern
2022-09-12 00:33:22 +03:00
committed by GitHub
parent 2157f1849e
commit 351c6aa798

View File

@ -1031,6 +1031,7 @@ class MapRegions (val ruleset: Ruleset){
it.assignedMinorCivs.add(civToAssign)
}
}
}
// STILL unassigned civs??
if (unassignedCivs.isNotEmpty()) {
@ -1043,7 +1044,6 @@ class MapRegions (val ruleset: Ruleset){
it.assignedMinorCivs.add(civToAssign)
}
}
}
// All minor civs are assigned - now place them
// First place the "uninhabited continent" ones, preferring coastal starts
@ -1053,86 +1053,10 @@ class MapRegions (val ruleset: Ruleset){
for (unplacedCiv in civAssignedToUninhabited) {
regions.random().assignedMinorCivs.add(unplacedCiv)
}
// Fallback lists for minor civs that can't be placed with any other method
val fallbackTiles = ArrayList<TileInfo>()
val fallbackMinors = ArrayList<CivilizationInfo>()
// Now place the ones assigned to specific regions.
for (region in regions) {
// Check the outer edges of the region, working inwards
val section = Rectangle(region.rect)
val unprocessedTiles = ArrayList<TileInfo>()
val regionCoastal = ArrayList<TileInfo>()
val regionHinterland = ArrayList<TileInfo>()
while (section.width >= 4 && section.height >= 4 && region.assignedMinorCivs.isNotEmpty()) {
// Clear the tile lists
unprocessedTiles.clear()
regionCoastal.clear()
regionHinterland.clear()
if (section.height > section.width) {
// Check top and bottom
unprocessedTiles.addAll(
tileMap.getTilesInRectangle(
Rectangle(section.x, section.y, section.width, 1f),
evenQ = true)
)
unprocessedTiles.addAll(
tileMap.getTilesInRectangle(
Rectangle(section.x, section.y + section.height - 1, section.width, 1f),
evenQ = true)
)
// Narrow the remaining section
section.y += 1
section.height -= 2
} else {
// Check left and right
unprocessedTiles.addAll(
tileMap.getTilesInRectangle(
Rectangle(section.x, section.y, 1f, section.height),
evenQ = true)
)
unprocessedTiles.addAll(
tileMap.getTilesInRectangle(
Rectangle(section.x + section.width - 1, section.y, 1f, section.height),
evenQ = true)
)
// Narrow the remaining section
section.x += 1
section.width -= 2
}
// Now process the tiles
for (tile in unprocessedTiles) {
if (!canPlaceMinorCiv(tile)) continue
if (!usingArchipelagoRegions && tile.getContinent() != region.continentID) continue
if(tile.isCoastalTile())
regionCoastal.add(tile)
else
regionHinterland.add(tile)
}
// Now attempt to place as many minor civs as possible, trying coastal tiles first
tryPlaceMinorCivsInTiles(region.assignedMinorCivs, tileMap, regionCoastal)
tryPlaceMinorCivsInTiles(region.assignedMinorCivs, tileMap, regionHinterland)
}
// In case we went through the entire region without finding spots for all assigned civs
if(region.assignedMinorCivs.isNotEmpty()) {
fallbackMinors.addAll(region.assignedMinorCivs)
} else {
// If we did find spots for all civs, there might be more eligible tiles left in the region
// Add them to the fallback list
fallbackTiles.addAll(regionCoastal)
fallbackTiles.addAll(regionHinterland)
fallbackTiles.addAll(tileMap.getTilesInRectangle(section, evenQ = true)
.filter { canPlaceMinorCiv(it) }
)
}
}
// Finally attempt to place the fallback lists - the rest will be silently discarded
if (fallbackMinors.isNotEmpty()) {
// Throw in the uninhabited lists as well
fallbackTiles.addAll(uninhabitedCoastal)
fallbackTiles.addAll(uninhabitedHinterland)
tryPlaceMinorCivsInTiles(fallbackMinors, tileMap, fallbackTiles)
tryPlaceMinorCivsInTiles(region.assignedMinorCivs, tileMap, region.tiles.toMutableList())
}
}