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
}
fun rankTileForCityWork(tile:TileInfo, city: CityInfo): Float {
fun rankTileForCityWork(tile:TileInfo, city: CityInfo, foodWeight: Float = 1f): Float {
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
if(city.population.population < 5){
// "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.science/2
rank += stats.culture/2
rank += stats.gold / 5 // it's barely worth anything at this points
}
else{
if (stats.food <= 2 || city.civInfo.getHappiness() > 5) rank += (stats.food * 1.2f) //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
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) * 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
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.unciv.Constants
import com.unciv.UnCivGame
import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.logic.map.BFS
import com.unciv.logic.map.MapUnit
@ -24,7 +25,7 @@ class WorkerAutomation(val unit: MapUnit) {
val tileToWork = findTileToWork()
if (getPriority(tileToWork, unit.civInfo) < 3) { // building roads is more important
if (tryConnectingCities()) return
if (tryConnectingCities(unit)) return
}
if (tileToWork != currentTile) {
@ -41,7 +42,7 @@ class WorkerAutomation(val unit: MapUnit) {
}
}
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>()
for (city in unit.civInfo.cities) {
@ -53,7 +54,7 @@ class WorkerAutomation(val unit: MapUnit) {
.filter { citiesToNumberOfUnimprovedTiles[it.name]!! > 0 }
.sortedByDescending { citiesToNumberOfUnimprovedTiles[it.name] }
.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)
if (reachedTile != currentTile) unit.doPreTurnAction() // since we've moved, maybe we can do something here - automate
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()

View File

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

View File

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

View File

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

View File

@ -80,6 +80,12 @@ class WorldScreenOptionsTable(val worldScreen:WorldScreen) : PopupTable(worldScr
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.addButton(if(settings.showMinimap) "Yes".tr() else "No".tr()) {
settings.showMinimap= !settings.showMinimap