AI changes (#12109)

* AI behaviour changes

* Update Automation.kt

* Update Automation.kt

* Update Automation.kt

* Update Automation.kt

* Update Automation.kt

* Update ConstructionAutomation.kt

* Update Automation.kt

* Reverting some changes

* Changes

* revert changes

* revert changes

* revert changes

* revert changes

* Update CityLocationTileRanker.kt

* Citizen assignment for stat conversion

* Update CityLocationTileRanker.kt

* Reduce AI settling

* Avoid AI building units when in negative Supply

* Update CityLocationTileRanker.kt

* Update CityLocationTileRanker.kt

* Update CityLocationTileRanker.kt

* Update ConstructionAutomation.kt

* Update build.gradle.kts

* Update gradle-wrapper.properties

* Update CityLocationTileRanker.kt

* Update CityLocationTileRanker.kt

* Update ConstructionAutomation.kt

* Update CityLocationTileRanker.kt

* AI changes for humans

* Fix puppet focus

* Update Automation.kt

* Puppet focus

* Update Automation.kt

* Update Automation.kt

* Update Automation.kt

* Update Automation.kt

* Update Automation.kt

* Update Automation.kt

* Update Automation.kt

* Update Automation.kt

* Update Automation.kt

* Update Stats.kt

* Update CityTurnManager.kt

* Remove specialist science modifier

* Update ReligionAutomation.kt

* Update ReligionAutomation.kt

* Update ReligionAutomation.kt

* Update CivilianUnitAutomation.kt

* Update ReligionAutomation.kt

* Worker prioritization

Workers are valuable in expand cities.

* Update ConstructionAutomation.kt

Food always important, it's rarely good to skip e.g. granary if we're on 6 pop.

* Update ConstructionAutomation.kt

Should achieve about the same with less lines of code.

* Update Automation.kt

* Update ConstructionAutomation.kt

* Update Policies.json

* Update Policies.json

* Update Policies.json

* Update ConstructionAutomation.kt

* Update Policies.json

* Update ReligionAutomation.kt

* Update ReligionAutomation.kt

* Update ReligionAutomation.kt

* Update ReligionAutomation.kt

* Rename Crop Yield to Growth
This commit is contained in:
EmperorPinguin 2024-08-17 20:40:20 +02:00 committed by GitHub
parent ff1596f0ce
commit 1a6d2279f5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 85 additions and 65 deletions

View File

@ -3,11 +3,11 @@
"name": "Tradition",
"era": "Ancient era",
"priorities": {
"Neutral": 0,
"Cultural": 10,
"Diplomatic": 0,
"Domination": 0,
"Scientific": 10
"Neutral": 5,
"Cultural": 5,
"Diplomatic": 5,
"Domination": 5,
"Scientific": 5
},
"uniques": [
"[+3 Culture] [in capital]",
@ -74,9 +74,9 @@
"priorities": {
"Neutral": 10,
"Cultural": 10,
"Diplomatic": 20,
"Domination": 20,
"Scientific": 20
"Diplomatic": 10,
"Domination": 10,
"Scientific": 10
},
"uniques": ["[+1 Culture] [in all cities]"],
"policies": [
@ -138,11 +138,11 @@
"name": "Honor",
"era": "Ancient era",
"priorities": {
"Neutral": 0,
"Cultural": 0,
"Diplomatic": 10,
"Domination": 10,
"Scientific": 0
"Neutral": 5,
"Cultural": 5,
"Diplomatic": 5,
"Domination": 5,
"Scientific": 5
},
"uniques": [
"[+33]% Strength <vs [Barbarian] units>",
@ -211,9 +211,9 @@
"era": "Classical era",
"priorities": {
"Neutral": 0,
"Cultural": 10,
"Diplomatic": 10,
"Domination": 10,
"Cultural": 0,
"Diplomatic": 0,
"Domination": 0,
"Scientific": 0
},
"uniques": [
@ -274,11 +274,11 @@
"name": "Patronage",
"era": "Medieval era",
"priorities": {
"Neutral": 0,
"Cultural": 10,
"Diplomatic": 20,
"Domination": 0,
"Scientific": 10
"Neutral": 5,
"Cultural": 5,
"Diplomatic": 10,
"Domination": 5,
"Scientific": 5
},
"uniques": ["[-25]% City-State Influence degradation"],
"policies": [
@ -339,11 +339,11 @@
"name": "Commerce",
"era": "Medieval era",
"priorities": {
"Neutral": 0,
"Cultural": 10,
"Diplomatic": 10,
"Domination": 10,
"Scientific": 10
"Neutral": 5,
"Cultural": 5,
"Diplomatic": 5,
"Domination": 5,
"Scientific": 5
},
"uniques": ["[+25]% [Gold] [in capital]"],
"policies": [
@ -410,11 +410,11 @@
"name": "Rationalism",
"era": "Renaissance era",
"priorities": {
"Neutral": 0,
"Neutral": 10,
"Cultural": 10,
"Diplomatic": 10,
"Domination": 10,
"Scientific": 60
"Scientific": 10
},
"uniques": [
"[+15]% [Science] <while the empire is happy>",
@ -476,11 +476,11 @@
"name": "Freedom",
"era": "Industrial era",
"priorities": {
"Neutral": 50,
"Cultural": 50,
"Diplomatic": 50,
"Domination": 40,
"Scientific": 50
"Neutral": 5,
"Cultural": 10,
"Diplomatic": 5,
"Domination": 5,
"Scientific": 10
},
"uniques": [
"[+25]% Great Person generation [in all cities]",
@ -538,11 +538,11 @@
"name": "Autocracy",
"era": "Industrial era",
"priorities": {
"Neutral": 50,
"Cultural": 40,
"Diplomatic": 40,
"Domination": 50,
"Scientific": 40
"Neutral": 5,
"Cultural": 5,
"Diplomatic": 5,
"Domination": 10,
"Scientific": 5
},
"uniques": [
"[-33]% maintenance costs <for [All] units>",
@ -607,11 +607,11 @@
"name": "Order",
"era": "Industrial era",
"priorities": {
"Neutral": 50,
"Cultural": 40,
"Diplomatic": 50,
"Domination": 40,
"Scientific": 50
"Neutral": 10,
"Cultural": 5,
"Diplomatic": 10,
"Domination": 5,
"Scientific": 5
},
"uniques": [
"[+1 Happiness] [in all cities]",

View File

@ -79,8 +79,8 @@ object Automation {
// Focus on non-food/growth
if (surplusFood < 0)
yieldStats.food *= 8 // Starving, need Food, get to 0
else
yieldStats.food /= 2
else if (city.civ.getHappiness() < 1)
yieldStats.food /= 4
} else if (!city.avoidGrowth) {
// NoFocus or Food/Growth Focus. Target +10 Food Surplus when happy
if (surplusFood < 0)

View File

@ -248,13 +248,13 @@ class ConstructionAutomation(val cityConstructions: CityConstructions) {
val numberOfWorkersWeWant = if (cities <= 5) cities else 5 + (cities - 5 / 2)
if (workers < numberOfWorkersWeWant) {
var modifier = numberOfWorkersWeWant / (workers + 0.4f) // The worse our worker to city ratio is, the more desperate we are
if (!cityIsOverAverageProduction) modifier /= 5 // higher production cities will deal with this
val modifier = numberOfWorkersWeWant / (workers + 0.4f) // The worse our worker to city ratio is, the more desperate we are
addChoice(relativeCostEffectiveness, workerEquivalents.minByOrNull { it.cost }!!.name, modifier)
}
}
private fun addSpaceshipPartChoice() {
if (!cityIsOverAverageProduction) return // don't waste time building them in low-production cities
if (!civInfo.hasUnique(UniqueType.EnablesConstructionOfSpaceshipParts)) return
val spaceshipPart = (nonWonders + units).filter { it.name in spaceshipParts }.filterBuildable().firstOrNull()
?: return
@ -328,25 +328,18 @@ class ConstructionAutomation(val cityConstructions: CityConstructions) {
val surplusFood = city.cityStats.currentCityStats[Stat.Food]
if (surplusFood < 0) {
buildingStats.food *= 8 // Starving, need Food, get to 0
} else if (city.population.population < 5) {
buildingStats.food *= 3
} else buildingStats.food *= 3
if (civInfo.stats.statsForNextTurn.gold < 10) {
buildingStats.gold *= 2 // We have a gold problem and need to adjust build queue accordingly
}
if (buildingStats.gold < 0 && civInfo.stats.statsForNextTurn.gold < 10) {
buildingStats.gold *= 2 // We have a gold problem and this isn't helping
}
if (civInfo.getHappiness() < 10 || civInfo.getHappiness() < civInfo.cities.size)
buildingStats.happiness * 5
if (civInfo.getHappiness() < 5)
buildingStats.happiness * 3
else if (civInfo.getHappiness() < 10 || civInfo.getHappiness() < civInfo.cities.size)
buildingStats.happiness * 2
if (city.cityStats.currentCityStats.culture < 1) {
if (city.cityStats.currentCityStats.culture < 2) {
buildingStats.culture *= 2 // We need to start growing borders
}
else if (city.tiles.size < 12 && city.population.population < 5) {
buildingStats.culture *= 2
}
for (stat in Stat.entries) {
if (civInfo.wantsToFocusOn(stat))

View File

@ -31,10 +31,14 @@ object ReligionAutomation {
return
}
if (civInfo.religionManager.remainingFoundableReligions() == 0 && civInfo.religionManager.religionState == ReligionState.Pantheon) {
buyGreatPerson(civInfo)
return
}
// We don't have a religion and no more change of getting it :(
if (civInfo.religionManager.religionState <= ReligionState.Pantheon) {
tryBuyAnyReligiousBuilding(civInfo)
// Todo: buy Great People post industrial era
return
}
@ -193,6 +197,29 @@ object ReligionAutomation {
cityToBuy.cityConstructions.purchaseConstruction(inquisitorConstruction, -1, true, Stat.Faith)
}
private fun buyGreatPerson(civInfo: Civilization) {
val greatPersonUnit = civInfo.gameInfo.ruleset.units.values.filter {
it.hasUnique(UniqueType.GreatPerson) && !it.hasUnique(UniqueType.MayFoundReligion) //we want to exclude great prophets from the list
}
val greatPersonConstruction = greatPersonUnit
// Get list of cities it can be built in
.associateBy({unit -> unit}) { unit -> civInfo.cities.filter { unit.isPurchasable(it.cityConstructions) && unit.canBePurchasedWithStat(it, Stat.Faith) } }
.filter { it.value.isNotEmpty() }
// And from that list determine the cheapest price
.minByOrNull { it.value.minOf { city -> it.key.getStatBuyCost(city, Stat.Faith)!! }}?.key
?: return
val validCitiesToBuy = civInfo.cities.filter {
(greatPersonConstruction.getStatBuyCost(it, Stat.Faith) ?: return@filter false) <= civInfo.religionManager.storedFaith
}
if (validCitiesToBuy.isEmpty()) return
val cityToBuy = validCitiesToBuy.first()
cityToBuy.cityConstructions.purchaseConstruction(greatPersonConstruction, -1, true, Stat.Faith)
}
// endregion
// region rate beliefs

View File

@ -146,7 +146,7 @@ object CivilianUnitAutomation {
private fun isLateGame(civ: Civilization): Boolean {
val researchCompletePercent =
(civ.tech.researchedTechnologies.size * 1.0f) / civ.gameInfo.ruleset.technologies.size
return researchCompletePercent >= 0.8f
return researchCompletePercent >= 0.7f
}
/** Returns whether the civilian spends its turn hiding and not moving */

View File

@ -677,7 +677,7 @@ class Civilization : IsPartOfGameInfoSerialization {
else when (category) {
RankingType.Score -> calculateTotalScore().toInt()
RankingType.Population -> cities.sumOf { it.population.population }
RankingType.CropYield -> stats.statsForNextTurn.food.roundToInt()
RankingType.Growth -> stats.statsForNextTurn.food.roundToInt()
RankingType.Production -> stats.statsForNextTurn.production.roundToInt()
RankingType.Gold -> gold
RankingType.Territory -> cities.sumOf { it.tiles.size }

View File

@ -12,7 +12,7 @@ enum class RankingType(
// production, gold, happiness, and culture already have icons added when the line is `tr()`anslated
Score({ ImageGetter.getImage("OtherIcons/Score").apply { color = Color.FIREBRICK } }, 'S'),
Population({ ImageGetter.getStatIcon("Population") }, 'N'),
CropYield("Crop Yield", { ImageGetter.getStatIcon("Food") }, 'C'),
Growth("Growth", { ImageGetter.getStatIcon("Food") }, 'C'),
Production('P'),
Gold('G'),
Territory({ ImageGetter.getImage("OtherIcons/Hexagon") }, 'T'),