Added setting about auto-build roads. (#1181)

* Added setting about auto-build roads.

* AI tries to keep population growing if possible.
This commit is contained in:
Duan Tao 2019-10-11 17:46:57 +08:00 committed by Yair Morgenstern
parent a8dac82157
commit c8e68842e9
6 changed files with 36 additions and 18 deletions

View File

@ -23,24 +23,24 @@ class Automation {
return rank return rank
} }
fun rankTileForCityWork(tile:TileInfo, city: CityInfo): Float { fun rankTileForCityWork(tile:TileInfo, city: CityInfo, foodWeight: Float = 1f): Float {
val stats = tile.getTileStats(city, city.civInfo) val stats = tile.getTileStats(city, city.civInfo)
return rankStatsForCityWork(stats, city) return rankStatsForCityWork(stats, city, foodWeight)
} }
private fun rankStatsForCityWork(stats: Stats, city: CityInfo): Float { private fun rankStatsForCityWork(stats: Stats, city: CityInfo, foodWeight: Float = 1f): Float {
var rank = 0f var rank = 0f
if(city.population.population < 5){ if(city.population.population < 5){
// "small city" - we care more about food and less about global problems like gold science and culture // "small city" - we care more about food and less about global problems like gold science and culture
rank += stats.food * 1.2f rank += stats.food * 1.2f * foodWeight
rank += stats.production rank += stats.production
rank += stats.science/2 rank += stats.science/2
rank += stats.culture/2 rank += stats.culture/2
rank += stats.gold / 5 // it's barely worth anything at this points rank += stats.gold / 5 // it's barely worth anything at this points
} }
else{ else{
if (stats.food <= 2 || city.civInfo.getHappiness() > 5) rank += (stats.food * 1.2f) //food get more value to keep city growing if (stats.food <= 2 || city.civInfo.getHappiness() > 5) rank += (stats.food * 1.2f * foodWeight) //food get more value to keep city growing
else rank += (2.4f + (stats.food - 2) / 2) // 1.2 point for each food up to 2, from there on half a point else rank += ((2.4f + (stats.food - 2) / 2) * foodWeight) // 1.2 point for each food up to 2, from there on half a point
if (city.civInfo.gold < 0 && city.civInfo.statsForNextTurn.gold <= 0) rank += stats.gold // we have a global problem if (city.civInfo.gold < 0 && city.civInfo.statsForNextTurn.gold <= 0) rank += stats.gold // we have a global problem
else rank += stats.gold / 3 // 3 gold is worse than 2 production else rank += stats.gold / 3 // 3 gold is worse than 2 production

View File

@ -2,6 +2,7 @@ package com.unciv.logic.automation
import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.graphics.Color
import com.unciv.Constants import com.unciv.Constants
import com.unciv.UnCivGame
import com.unciv.logic.civilization.CivilizationInfo import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.logic.map.BFS import com.unciv.logic.map.BFS
import com.unciv.logic.map.MapUnit import com.unciv.logic.map.MapUnit
@ -24,7 +25,7 @@ class WorkerAutomation(val unit: MapUnit) {
val tileToWork = findTileToWork() val tileToWork = findTileToWork()
if (getPriority(tileToWork, unit.civInfo) < 3) { // building roads is more important if (getPriority(tileToWork, unit.civInfo) < 3) { // building roads is more important
if (tryConnectingCities()) return if (tryConnectingCities(unit)) return
} }
if (tileToWork != currentTile) { if (tileToWork != currentTile) {
@ -41,7 +42,7 @@ class WorkerAutomation(val unit: MapUnit) {
} }
} }
if (currentTile.improvementInProgress != null) return // we're working! if (currentTile.improvementInProgress != null) return // we're working!
if (tryConnectingCities()) return //nothing to do, try again to connect cities if (tryConnectingCities(unit)) return //nothing to do, try again to connect cities
val citiesToNumberOfUnimprovedTiles = HashMap<String, Int>() val citiesToNumberOfUnimprovedTiles = HashMap<String, Int>()
for (city in unit.civInfo.cities) { for (city in unit.civInfo.cities) {
@ -53,7 +54,7 @@ class WorkerAutomation(val unit: MapUnit) {
.filter { citiesToNumberOfUnimprovedTiles[it.name]!! > 0 } .filter { citiesToNumberOfUnimprovedTiles[it.name]!! > 0 }
.sortedByDescending { citiesToNumberOfUnimprovedTiles[it.name] } .sortedByDescending { citiesToNumberOfUnimprovedTiles[it.name] }
.firstOrNull { unit.movement.canReach(it.ccenterTile) } //goto most undeveloped city .firstOrNull { unit.movement.canReach(it.ccenterTile) } //goto most undeveloped city
if (mostUndevelopedCity != null) { if (mostUndevelopedCity != null && mostUndevelopedCity != unit.currentTile.owningCity) {
val reachedTile = unit.movement.headTowards(mostUndevelopedCity.ccenterTile) val reachedTile = unit.movement.headTowards(mostUndevelopedCity.ccenterTile)
if (reachedTile != currentTile) unit.doPreTurnAction() // since we've moved, maybe we can do something here - automate if (reachedTile != currentTile) unit.doPreTurnAction() // since we've moved, maybe we can do something here - automate
return return
@ -64,7 +65,10 @@ class WorkerAutomation(val unit: MapUnit) {
private fun tryConnectingCities():Boolean { // returns whether we actually did anything private fun tryConnectingCities(unit: MapUnit):Boolean { // returns whether we actually did anything
//Player can choose not to auto-build roads & railroads.
if (unit.civInfo.isPlayerCivilization() && !UnCivGame.Current.settings.autoBuildingRoads)
return false
val targetRoad = unit.civInfo.tech.getBestRoadAvailable() val targetRoad = unit.civInfo.tech.getBestRoadAvailable()

View File

@ -229,11 +229,18 @@ class CityInfo {
} }
fun reassignWorkers() { fun reassignWorkers() {
var foodWeight = 1f
var foodPerTurn = 0f
while (foodWeight < 3 && foodPerTurn <= 0) {
workedTiles = hashSetOf() workedTiles = hashSetOf()
population.specialists.clear() population.specialists.clear()
for (i in 0..population.population) for (i in 0..population.population)
population.autoAssignPopulation() population.autoAssignPopulation(foodWeight)
cityStats.update() cityStats.update()
foodPerTurn = cityStats.currentCityStats.food
foodWeight += 0.5f
}
} }
fun endTurn() { fun endTurn() {

View File

@ -73,16 +73,16 @@ class PopulationManager {
// todo - change tile choice according to city! // todo - change tile choice according to city!
// if small city, favor production above all, ignore gold! // if small city, favor production above all, ignore gold!
// if larger city, food should be worth less! // if larger city, food should be worth less!
internal fun autoAssignPopulation() { internal fun autoAssignPopulation(foodWeight: Float = 1f) {
if(getFreePopulation()==0) return if(getFreePopulation()==0) return
//evaluate tiles //evaluate tiles
val bestTile: TileInfo? = cityInfo.getTiles() 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().rankTileForCityWork(it,cityInfo) } .maxBy { Automation().rankTileForCityWork(it,cityInfo, foodWeight) }
val valueBestTile = if(bestTile==null) 0f val valueBestTile = if(bestTile==null) 0f
else Automation().rankTileForCityWork(bestTile, cityInfo) else Automation().rankTileForCityWork(bestTile, cityInfo, foodWeight)
//evaluate specialists //evaluate specialists
val maxSpecialistsMap = getMaxSpecialists().toHashMap() val maxSpecialistsMap = getMaxSpecialists().toHashMap()

View File

@ -17,6 +17,7 @@ class GameSettings {
var tileSet:String = "FantasyHex" var tileSet:String = "FantasyHex"
var showTutorials: Boolean = true var showTutorials: Boolean = true
var autoAssignCityProduction: Boolean = true var autoAssignCityProduction: Boolean = true
var autoBuildingRoads: Boolean = true
var showMinimap: Boolean = true var showMinimap: Boolean = true
var userName:String="" var userName:String=""

View File

@ -80,6 +80,12 @@ class WorldScreenOptionsTable(val worldScreen:WorldScreen) : PopupTable(worldScr
update() update()
} }
innerTable.add("Auto-build roads".toLabel())
innerTable.addButton(if(settings.autoBuildingRoads) "Yes".tr() else "No".tr()) {
settings.autoBuildingRoads= !settings.autoBuildingRoads
update()
}
innerTable.add("Show minimap".toLabel()) innerTable.add("Show minimap".toLabel())
innerTable.addButton(if(settings.showMinimap) "Yes".tr() else "No".tr()) { innerTable.addButton(if(settings.showMinimap) "Yes".tr() else "No".tr()) {
settings.showMinimap= !settings.showMinimap settings.showMinimap= !settings.showMinimap