Fix off-by-one error in autoAssignPopulation (#9411)

* Fix off-by-one error in autoAssignPopulation

* Fix more off-by-one errors from for-repeat conversions

* Linting: Use Actions.forever shortcut where appropriate
This commit is contained in:
SomeTroglodyte 2023-05-21 11:08:03 +02:00 committed by GitHub
parent ec4586af6c
commit a91dca0930
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 21 additions and 26 deletions

View File

@ -688,7 +688,7 @@ object NextTurnAutomation {
// not have used a great prophet to found/enhance our religion. // not have used a great prophet to found/enhance our religion.
for (belief in BeliefType.values()) { for (belief in BeliefType.values()) {
if (belief == BeliefType.None) continue if (belief == BeliefType.None) continue
repeat((beliefsToChoose[belief] ?: 0) - 1) { repeat(beliefsToChoose[belief] ?: 0) {
chosenBeliefs.add( chosenBeliefs.add(
chooseBeliefOfType(civInfo, belief, chosenBeliefs) ?: return@repeat chooseBeliefOfType(civInfo, belief, chosenBeliefs) ?: return@repeat
) )

View File

@ -154,42 +154,37 @@ class CityPopulationManager : IsPartOfGameInfoSerialization {
specialistFoodBonus *= unique.params[0].toPercent() specialistFoodBonus *= unique.params[0].toPercent()
specialistFoodBonus = 2f - specialistFoodBonus specialistFoodBonus = 2f - specialistFoodBonus
val currentCiv = city.civ val tilesToEvaluate = city.getWorkableTiles()
.filter { !it.isBlockaded() }.toList().asSequence()
val tilesToEvaluate = city.getCenterTile().getTilesInDistance(3)
.filter { it.getOwner() == currentCiv && !it.isBlockaded() }.toList().asSequence()
val localUniqueCache = LocalUniqueCache() val localUniqueCache = LocalUniqueCache()
repeat(getFreePopulation() - 1) { repeat(getFreePopulation()) {
//evaluate tiles //evaluate tiles
val (bestTile, valueBestTile) = tilesToEvaluate val bestTileAndRank = tilesToEvaluate
.filterNot { it.providesYield() } .filterNot { it.providesYield() }
.associateWith { Automation.rankTileForCityWork(it, city, cityStats, localUniqueCache) } .associateWith { Automation.rankTileForCityWork(it, city, cityStats, localUniqueCache) }
.maxByOrNull { it.value } .maxByOrNull { it.value }
?: object : Map.Entry<Tile?, Float> { val bestTile = bestTileAndRank?.key
override val key: Tile? = null val valueBestTile = bestTileAndRank?.value ?: 0f
override val value = 0f
}
val bestJob: String? = if (city.manualSpecialists) null else getMaxSpecialists() val bestJobAndRank = if (city.manualSpecialists) null
else getMaxSpecialists().asSequence()
.filter { specialistAllocations[it.key]!! < it.value } .filter { specialistAllocations[it.key]!! < it.value }
.map { it.key } .map { it.key }
.maxByOrNull { Automation.rankSpecialist(it, city, cityStats, localUniqueCache) } .associateWith { Automation.rankSpecialist(it, city, cityStats, localUniqueCache) }
.maxByOrNull { it.value }
var valueBestSpecialist = 0f val bestJob = bestJobAndRank?.key
if (bestJob != null) { val valueBestSpecialist = bestJobAndRank?.value ?: 0f
valueBestSpecialist = Automation.rankSpecialist(bestJob, city, cityStats, localUniqueCache)
}
//assign population //assign population
if (valueBestTile > valueBestSpecialist) { if (valueBestTile > valueBestSpecialist) {
if (bestTile != null) { if (bestTile != null) {
city.workedTiles = city.workedTiles.withItem(bestTile.position) city.workedTiles = city.workedTiles.withItem(bestTile.position)
cityStats[Stat.Food] += bestTile.stats.getTileStats(city, city.civ, localUniqueCache)[Stat.Food] cityStats.food += bestTile.stats.getTileStats(city, city.civ, localUniqueCache).food
} }
} else if (bestJob != null) { } else if (bestJob != null) {
specialistAllocations.add(bestJob, 1) specialistAllocations.add(bestJob, 1)
cityStats[Stat.Food] += specialistFoodBonus cityStats.food += specialistFoodBonus
} }
} }
city.cityStats.update() city.cityStats.update()

View File

@ -46,7 +46,7 @@ object Perlin {
var amp = 1.0 var amp = 1.0
var max = 0.0 var max = 0.0
var total = 0.0 var total = 0.0
repeat(nOctaves - 1) { repeat(nOctaves) {
total += amp * noise(x * freq / scale, y * freq / scale, z * freq / scale) total += amp * noise(x * freq / scale, y * freq / scale, z * freq / scale)
max += amp max += amp
freq *= lacunarity freq *= lacunarity

View File

@ -60,7 +60,7 @@ class VerticalFileListScrollPane(
val loadImage = ImageGetter.getImage("OtherIcons/Load") val loadImage = ImageGetter.getImage("OtherIcons/Load")
loadImage.setSize(50f, 50f) // So the origin sets correctly loadImage.setSize(50f, 50f) // So the origin sets correctly
loadImage.setOrigin(Align.center) loadImage.setOrigin(Align.center)
val loadAnimation = Actions.repeat(Int.MAX_VALUE, Actions.rotateBy(360f, 2f)) val loadAnimation = Actions.forever(Actions.rotateBy(360f, 2f))
loadImage.addAction(loadAnimation) loadImage.addAction(loadAnimation)
existingSavesTable.add(loadImage).size(50f).center() existingSavesTable.add(loadImage).size(50f).center()

View File

@ -237,11 +237,11 @@ object BattleTableHelpers {
val damagedHealth = ImageGetter.getDot(Color.FIREBRICK) val damagedHealth = ImageGetter.getDot(Color.FIREBRICK)
if (UncivGame.Current.settings.continuousRendering) { if (UncivGame.Current.settings.continuousRendering) {
damagedHealth.addAction(Actions.repeat( damagedHealth.addAction(Actions.forever(Actions.sequence(
RepeatAction.FOREVER, Actions.sequence(
Actions.color(Color.BLACK, 0.7f), Actions.color(Color.BLACK, 0.7f),
Actions.color(Color.FIREBRICK, 0.7f) Actions.color(Color.FIREBRICK, 0.7f)
))) } )))
}
val maybeDamagedHealth = ImageGetter.getDot(Color.ORANGE) val maybeDamagedHealth = ImageGetter.getDot(Color.ORANGE)

View File

@ -82,7 +82,7 @@ class MultiplayerStatusButton(
if (UncivGame.Current.settings.continuousRendering) { if (UncivGame.Current.settings.continuousRendering) {
loadingImage.clearActions() loadingImage.clearActions()
loadingImage.addAction(Actions.repeat(RepeatAction.FOREVER,Actions.rotateBy(-90f, 1f))) loadingImage.addAction(Actions.forever(Actions.rotateBy(-90f, 1f)))
} }
loadingImage.isVisible = true loadingImage.isVisible = true