mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-27 22:06:05 -04:00
Allow auto assign population to specialists.
This commit is contained in:
parent
7cacff0a37
commit
173a773271
@ -4,18 +4,36 @@ import com.badlogic.gdx.graphics.Color
|
|||||||
import com.unciv.logic.battle.CityCombatant
|
import com.unciv.logic.battle.CityCombatant
|
||||||
import com.unciv.logic.city.CityConstructions
|
import com.unciv.logic.city.CityConstructions
|
||||||
import com.unciv.logic.city.CityInfo
|
import com.unciv.logic.city.CityInfo
|
||||||
|
import com.unciv.logic.city.CityStats
|
||||||
import com.unciv.logic.civilization.CivilizationInfo
|
import com.unciv.logic.civilization.CivilizationInfo
|
||||||
import com.unciv.logic.map.TileInfo
|
import com.unciv.logic.map.TileInfo
|
||||||
import com.unciv.models.gamebasics.unit.BaseUnit
|
import com.unciv.models.gamebasics.unit.BaseUnit
|
||||||
import com.unciv.models.gamebasics.unit.UnitType
|
import com.unciv.models.gamebasics.unit.UnitType
|
||||||
|
import com.unciv.models.stats.Stat
|
||||||
|
import com.unciv.models.stats.Stats
|
||||||
import com.unciv.ui.utils.getRandom
|
import com.unciv.ui.utils.getRandom
|
||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
import kotlin.math.sqrt
|
import kotlin.math.sqrt
|
||||||
|
|
||||||
class Automation {
|
class Automation {
|
||||||
|
|
||||||
internal fun rankTile(tile: TileInfo, civInfo: CivilizationInfo): Float {
|
internal fun rankTile(tile: TileInfo?, civInfo: CivilizationInfo): Float {
|
||||||
|
if (tile == null) return 0.0f
|
||||||
val stats = tile.getTileStats(null, civInfo)
|
val stats = tile.getTileStats(null, civInfo)
|
||||||
|
var rank = rankStatsValue(stats, civInfo)
|
||||||
|
if (tile.improvement == null) rank += 0.5f // improvement potential!
|
||||||
|
if (tile.hasViewableResource(civInfo)) rank += 1.0f
|
||||||
|
return rank
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun rankSpecialist(stats: Stats?, civInfo: CivilizationInfo): Float {
|
||||||
|
if (stats == null) return 0.0f
|
||||||
|
var rank = rankStatsValue(stats, civInfo)
|
||||||
|
rank += 0.3f //GPP bonus
|
||||||
|
return rank
|
||||||
|
}
|
||||||
|
|
||||||
|
fun rankStatsValue(stats: Stats, civInfo: CivilizationInfo): Float {
|
||||||
var rank = 0.0f
|
var rank = 0.0f
|
||||||
if (stats.food <= 2) rank += stats.food
|
if (stats.food <= 2) rank += stats.food
|
||||||
else rank += (2 + (stats.food - 2) / 2) // 1 point for each food up to 2, from there on half a point
|
else rank += (2 + (stats.food - 2) / 2) // 1 point for each food up to 2, from there on half a point
|
||||||
@ -26,8 +44,6 @@ class Automation {
|
|||||||
rank += stats.production
|
rank += stats.production
|
||||||
rank += stats.science
|
rank += stats.science
|
||||||
rank += stats.culture
|
rank += stats.culture
|
||||||
if (tile.improvement == null) rank += 0.5f // improvement potential!
|
|
||||||
if (tile.hasViewableResource(civInfo)) rank += 1.0f
|
|
||||||
return rank
|
return rank
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ package com.unciv.logic.city
|
|||||||
import com.badlogic.gdx.graphics.Color
|
import com.badlogic.gdx.graphics.Color
|
||||||
import com.unciv.logic.automation.Automation
|
import com.unciv.logic.automation.Automation
|
||||||
import com.unciv.logic.map.TileInfo
|
import com.unciv.logic.map.TileInfo
|
||||||
|
import com.unciv.models.stats.Stat
|
||||||
import com.unciv.models.stats.Stats
|
import com.unciv.models.stats.Stats
|
||||||
import com.unciv.ui.utils.getRandom
|
import com.unciv.ui.utils.getRandom
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
@ -70,12 +71,34 @@ class PopulationManager {
|
|||||||
|
|
||||||
internal fun autoAssignPopulation() {
|
internal fun autoAssignPopulation() {
|
||||||
if(getFreePopulation()==0) return
|
if(getFreePopulation()==0) return
|
||||||
val toWork: TileInfo? = cityInfo.getTiles()
|
|
||||||
|
//evaluate tiles
|
||||||
|
val bestTile: TileInfo? = cityInfo.getTiles()
|
||||||
.filter { it.arialDistanceTo(cityInfo.getCenterTile()) <= 3 }
|
.filter { it.arialDistanceTo(cityInfo.getCenterTile()) <= 3 }
|
||||||
.filterNot { cityInfo.workedTiles.contains(it.position) || cityInfo.location==it.position}
|
.filterNot { cityInfo.workedTiles.contains(it.position) || cityInfo.location==it.position}
|
||||||
.maxBy { Automation().rankTile(it,cityInfo.civInfo) }
|
.maxBy { Automation().rankTile(it,cityInfo.civInfo) }
|
||||||
if (toWork != null) // This is when we've run out of tiles!
|
val valueBestTile = Automation().rankTile(bestTile, cityInfo.civInfo)
|
||||||
cityInfo.workedTiles.add(toWork.position)
|
|
||||||
|
//evaluate specialists
|
||||||
|
val maxSpecialistsMap = getMaxSpecialists().toHashMap()
|
||||||
|
val policies = cityInfo.civInfo.policies.adoptedPolicies
|
||||||
|
val bestJob: Stat? = specialists.toHashMap()
|
||||||
|
.filter {maxSpecialistsMap.containsKey(it.key) && it.value < maxSpecialistsMap[it.key]!!}
|
||||||
|
.maxBy { Automation().rankSpecialist(cityInfo.cityStats.getStatsOfSpecialist(it.key, policies), cityInfo.civInfo) }
|
||||||
|
?.key
|
||||||
|
var valueBestSpecialist = 0f
|
||||||
|
if (bestJob != null)
|
||||||
|
valueBestSpecialist = Automation().rankSpecialist(cityInfo.cityStats.getStatsOfSpecialist(bestJob, policies), cityInfo.civInfo)
|
||||||
|
|
||||||
|
//assign population
|
||||||
|
if (valueBestTile > valueBestSpecialist) {
|
||||||
|
if (bestTile != null)
|
||||||
|
cityInfo.workedTiles.add(bestTile.position)
|
||||||
|
} else {
|
||||||
|
if (bestJob != null) {
|
||||||
|
specialists.add(bestJob, 1f)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun unassignExtraPopulation() {
|
fun unassignExtraPopulation() {
|
||||||
@ -87,16 +110,29 @@ class PopulationManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
while (getFreePopulation()<0) {
|
while (getFreePopulation()<0) {
|
||||||
if(getNumberOfSpecialists()>0){
|
//evaluate tiles
|
||||||
val specialistTypeToUnassign = specialists.toHashMap().filter { it.value>0 }.map { it.key }.getRandom()
|
val worstWorkedTile: TileInfo? = cityInfo.workedTiles
|
||||||
specialists.add(specialistTypeToUnassign,-1f)
|
.asSequence()
|
||||||
}
|
.map { cityInfo.tileMap[it] }
|
||||||
else {
|
.minBy { Automation().rankTile(it, cityInfo.civInfo) }!!
|
||||||
val lowestRankedWorkedTile = cityInfo.workedTiles
|
val valueWorstTile = Automation().rankTile(worstWorkedTile, cityInfo.civInfo)
|
||||||
.asSequence()
|
|
||||||
.map { cityInfo.tileMap[it] }
|
//evaluate specialists
|
||||||
.minBy { Automation().rankTile(it, cityInfo.civInfo) }!!
|
val policies = cityInfo.civInfo.policies.adoptedPolicies
|
||||||
cityInfo.workedTiles.remove(lowestRankedWorkedTile.position)
|
val worstJob: Stat? = specialists.toHashMap()
|
||||||
|
.filter { it.value > 0 }
|
||||||
|
.minBy { Automation().rankSpecialist(cityInfo.cityStats.getStatsOfSpecialist(it.key, policies), cityInfo.civInfo) }
|
||||||
|
?.key
|
||||||
|
var valueWorstSpecialist = 0f
|
||||||
|
if (worstJob != null)
|
||||||
|
valueWorstSpecialist = Automation().rankSpecialist(cityInfo.cityStats.getStatsOfSpecialist(worstJob, policies), cityInfo.civInfo)
|
||||||
|
|
||||||
|
//un-assign population
|
||||||
|
if ((valueWorstTile < valueWorstSpecialist && worstWorkedTile != null)
|
||||||
|
|| (getNumberOfSpecialists() == 0)) {
|
||||||
|
cityInfo.workedTiles.remove(worstWorkedTile!!.position)
|
||||||
|
} else {
|
||||||
|
specialists.add(worstJob!!, -1f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user