mirror of
https://github.com/yairm210/Unciv.git
synced 2025-02-08 01:54:02 +07:00
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:
parent
ff1596f0ce
commit
1a6d2279f5
@ -3,11 +3,11 @@
|
|||||||
"name": "Tradition",
|
"name": "Tradition",
|
||||||
"era": "Ancient era",
|
"era": "Ancient era",
|
||||||
"priorities": {
|
"priorities": {
|
||||||
"Neutral": 0,
|
"Neutral": 5,
|
||||||
"Cultural": 10,
|
"Cultural": 5,
|
||||||
"Diplomatic": 0,
|
"Diplomatic": 5,
|
||||||
"Domination": 0,
|
"Domination": 5,
|
||||||
"Scientific": 10
|
"Scientific": 5
|
||||||
},
|
},
|
||||||
"uniques": [
|
"uniques": [
|
||||||
"[+3 Culture] [in capital]",
|
"[+3 Culture] [in capital]",
|
||||||
@ -74,9 +74,9 @@
|
|||||||
"priorities": {
|
"priorities": {
|
||||||
"Neutral": 10,
|
"Neutral": 10,
|
||||||
"Cultural": 10,
|
"Cultural": 10,
|
||||||
"Diplomatic": 20,
|
"Diplomatic": 10,
|
||||||
"Domination": 20,
|
"Domination": 10,
|
||||||
"Scientific": 20
|
"Scientific": 10
|
||||||
},
|
},
|
||||||
"uniques": ["[+1 Culture] [in all cities]"],
|
"uniques": ["[+1 Culture] [in all cities]"],
|
||||||
"policies": [
|
"policies": [
|
||||||
@ -138,11 +138,11 @@
|
|||||||
"name": "Honor",
|
"name": "Honor",
|
||||||
"era": "Ancient era",
|
"era": "Ancient era",
|
||||||
"priorities": {
|
"priorities": {
|
||||||
"Neutral": 0,
|
"Neutral": 5,
|
||||||
"Cultural": 0,
|
"Cultural": 5,
|
||||||
"Diplomatic": 10,
|
"Diplomatic": 5,
|
||||||
"Domination": 10,
|
"Domination": 5,
|
||||||
"Scientific": 0
|
"Scientific": 5
|
||||||
},
|
},
|
||||||
"uniques": [
|
"uniques": [
|
||||||
"[+33]% Strength <vs [Barbarian] units>",
|
"[+33]% Strength <vs [Barbarian] units>",
|
||||||
@ -211,9 +211,9 @@
|
|||||||
"era": "Classical era",
|
"era": "Classical era",
|
||||||
"priorities": {
|
"priorities": {
|
||||||
"Neutral": 0,
|
"Neutral": 0,
|
||||||
"Cultural": 10,
|
"Cultural": 0,
|
||||||
"Diplomatic": 10,
|
"Diplomatic": 0,
|
||||||
"Domination": 10,
|
"Domination": 0,
|
||||||
"Scientific": 0
|
"Scientific": 0
|
||||||
},
|
},
|
||||||
"uniques": [
|
"uniques": [
|
||||||
@ -274,11 +274,11 @@
|
|||||||
"name": "Patronage",
|
"name": "Patronage",
|
||||||
"era": "Medieval era",
|
"era": "Medieval era",
|
||||||
"priorities": {
|
"priorities": {
|
||||||
"Neutral": 0,
|
"Neutral": 5,
|
||||||
"Cultural": 10,
|
"Cultural": 5,
|
||||||
"Diplomatic": 20,
|
"Diplomatic": 10,
|
||||||
"Domination": 0,
|
"Domination": 5,
|
||||||
"Scientific": 10
|
"Scientific": 5
|
||||||
},
|
},
|
||||||
"uniques": ["[-25]% City-State Influence degradation"],
|
"uniques": ["[-25]% City-State Influence degradation"],
|
||||||
"policies": [
|
"policies": [
|
||||||
@ -339,11 +339,11 @@
|
|||||||
"name": "Commerce",
|
"name": "Commerce",
|
||||||
"era": "Medieval era",
|
"era": "Medieval era",
|
||||||
"priorities": {
|
"priorities": {
|
||||||
"Neutral": 0,
|
"Neutral": 5,
|
||||||
"Cultural": 10,
|
"Cultural": 5,
|
||||||
"Diplomatic": 10,
|
"Diplomatic": 5,
|
||||||
"Domination": 10,
|
"Domination": 5,
|
||||||
"Scientific": 10
|
"Scientific": 5
|
||||||
},
|
},
|
||||||
"uniques": ["[+25]% [Gold] [in capital]"],
|
"uniques": ["[+25]% [Gold] [in capital]"],
|
||||||
"policies": [
|
"policies": [
|
||||||
@ -410,11 +410,11 @@
|
|||||||
"name": "Rationalism",
|
"name": "Rationalism",
|
||||||
"era": "Renaissance era",
|
"era": "Renaissance era",
|
||||||
"priorities": {
|
"priorities": {
|
||||||
"Neutral": 0,
|
"Neutral": 10,
|
||||||
"Cultural": 10,
|
"Cultural": 10,
|
||||||
"Diplomatic": 10,
|
"Diplomatic": 10,
|
||||||
"Domination": 10,
|
"Domination": 10,
|
||||||
"Scientific": 60
|
"Scientific": 10
|
||||||
},
|
},
|
||||||
"uniques": [
|
"uniques": [
|
||||||
"[+15]% [Science] <while the empire is happy>",
|
"[+15]% [Science] <while the empire is happy>",
|
||||||
@ -476,11 +476,11 @@
|
|||||||
"name": "Freedom",
|
"name": "Freedom",
|
||||||
"era": "Industrial era",
|
"era": "Industrial era",
|
||||||
"priorities": {
|
"priorities": {
|
||||||
"Neutral": 50,
|
"Neutral": 5,
|
||||||
"Cultural": 50,
|
"Cultural": 10,
|
||||||
"Diplomatic": 50,
|
"Diplomatic": 5,
|
||||||
"Domination": 40,
|
"Domination": 5,
|
||||||
"Scientific": 50
|
"Scientific": 10
|
||||||
},
|
},
|
||||||
"uniques": [
|
"uniques": [
|
||||||
"[+25]% Great Person generation [in all cities]",
|
"[+25]% Great Person generation [in all cities]",
|
||||||
@ -538,11 +538,11 @@
|
|||||||
"name": "Autocracy",
|
"name": "Autocracy",
|
||||||
"era": "Industrial era",
|
"era": "Industrial era",
|
||||||
"priorities": {
|
"priorities": {
|
||||||
"Neutral": 50,
|
"Neutral": 5,
|
||||||
"Cultural": 40,
|
"Cultural": 5,
|
||||||
"Diplomatic": 40,
|
"Diplomatic": 5,
|
||||||
"Domination": 50,
|
"Domination": 10,
|
||||||
"Scientific": 40
|
"Scientific": 5
|
||||||
},
|
},
|
||||||
"uniques": [
|
"uniques": [
|
||||||
"[-33]% maintenance costs <for [All] units>",
|
"[-33]% maintenance costs <for [All] units>",
|
||||||
@ -607,11 +607,11 @@
|
|||||||
"name": "Order",
|
"name": "Order",
|
||||||
"era": "Industrial era",
|
"era": "Industrial era",
|
||||||
"priorities": {
|
"priorities": {
|
||||||
"Neutral": 50,
|
"Neutral": 10,
|
||||||
"Cultural": 40,
|
"Cultural": 5,
|
||||||
"Diplomatic": 50,
|
"Diplomatic": 10,
|
||||||
"Domination": 40,
|
"Domination": 5,
|
||||||
"Scientific": 50
|
"Scientific": 5
|
||||||
},
|
},
|
||||||
"uniques": [
|
"uniques": [
|
||||||
"[+1 Happiness] [in all cities]",
|
"[+1 Happiness] [in all cities]",
|
||||||
|
@ -79,8 +79,8 @@ object Automation {
|
|||||||
// Focus on non-food/growth
|
// Focus on non-food/growth
|
||||||
if (surplusFood < 0)
|
if (surplusFood < 0)
|
||||||
yieldStats.food *= 8 // Starving, need Food, get to 0
|
yieldStats.food *= 8 // Starving, need Food, get to 0
|
||||||
else
|
else if (city.civ.getHappiness() < 1)
|
||||||
yieldStats.food /= 2
|
yieldStats.food /= 4
|
||||||
} else if (!city.avoidGrowth) {
|
} else if (!city.avoidGrowth) {
|
||||||
// NoFocus or Food/Growth Focus. Target +10 Food Surplus when happy
|
// NoFocus or Food/Growth Focus. Target +10 Food Surplus when happy
|
||||||
if (surplusFood < 0)
|
if (surplusFood < 0)
|
||||||
|
@ -248,13 +248,13 @@ class ConstructionAutomation(val cityConstructions: CityConstructions) {
|
|||||||
val numberOfWorkersWeWant = if (cities <= 5) cities else 5 + (cities - 5 / 2)
|
val numberOfWorkersWeWant = if (cities <= 5) cities else 5 + (cities - 5 / 2)
|
||||||
|
|
||||||
if (workers < numberOfWorkersWeWant) {
|
if (workers < numberOfWorkersWeWant) {
|
||||||
var modifier = numberOfWorkersWeWant / (workers + 0.4f) // The worse our worker to city ratio is, the more desperate we are
|
val 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
|
|
||||||
addChoice(relativeCostEffectiveness, workerEquivalents.minByOrNull { it.cost }!!.name, modifier)
|
addChoice(relativeCostEffectiveness, workerEquivalents.minByOrNull { it.cost }!!.name, modifier)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addSpaceshipPartChoice() {
|
private fun addSpaceshipPartChoice() {
|
||||||
|
if (!cityIsOverAverageProduction) return // don't waste time building them in low-production cities
|
||||||
if (!civInfo.hasUnique(UniqueType.EnablesConstructionOfSpaceshipParts)) return
|
if (!civInfo.hasUnique(UniqueType.EnablesConstructionOfSpaceshipParts)) return
|
||||||
val spaceshipPart = (nonWonders + units).filter { it.name in spaceshipParts }.filterBuildable().firstOrNull()
|
val spaceshipPart = (nonWonders + units).filter { it.name in spaceshipParts }.filterBuildable().firstOrNull()
|
||||||
?: return
|
?: return
|
||||||
@ -328,25 +328,18 @@ class ConstructionAutomation(val cityConstructions: CityConstructions) {
|
|||||||
val surplusFood = city.cityStats.currentCityStats[Stat.Food]
|
val surplusFood = city.cityStats.currentCityStats[Stat.Food]
|
||||||
if (surplusFood < 0) {
|
if (surplusFood < 0) {
|
||||||
buildingStats.food *= 8 // Starving, need Food, get to 0
|
buildingStats.food *= 8 // Starving, need Food, get to 0
|
||||||
} else if (city.population.population < 5) {
|
} else buildingStats.food *= 3
|
||||||
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) {
|
if (civInfo.getHappiness() < 10 || civInfo.getHappiness() < civInfo.cities.size)
|
||||||
buildingStats.gold *= 2 // We have a gold problem and this isn't helping
|
buildingStats.happiness * 5
|
||||||
}
|
|
||||||
|
|
||||||
if (civInfo.getHappiness() < 5)
|
if (city.cityStats.currentCityStats.culture < 2) {
|
||||||
buildingStats.happiness * 3
|
|
||||||
else if (civInfo.getHappiness() < 10 || civInfo.getHappiness() < civInfo.cities.size)
|
|
||||||
buildingStats.happiness * 2
|
|
||||||
|
|
||||||
if (city.cityStats.currentCityStats.culture < 1) {
|
|
||||||
buildingStats.culture *= 2 // We need to start growing borders
|
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) {
|
for (stat in Stat.entries) {
|
||||||
if (civInfo.wantsToFocusOn(stat))
|
if (civInfo.wantsToFocusOn(stat))
|
||||||
|
@ -30,11 +30,15 @@ object ReligionAutomation {
|
|||||||
buyGreatProphetInAnyCity(civInfo)
|
buyGreatProphetInAnyCity(civInfo)
|
||||||
return
|
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 :(
|
// We don't have a religion and no more change of getting it :(
|
||||||
if (civInfo.religionManager.religionState <= ReligionState.Pantheon) {
|
if (civInfo.religionManager.religionState <= ReligionState.Pantheon) {
|
||||||
tryBuyAnyReligiousBuilding(civInfo)
|
tryBuyAnyReligiousBuilding(civInfo)
|
||||||
// Todo: buy Great People post industrial era
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,6 +197,29 @@ object ReligionAutomation {
|
|||||||
cityToBuy.cityConstructions.purchaseConstruction(inquisitorConstruction, -1, true, Stat.Faith)
|
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
|
// endregion
|
||||||
|
|
||||||
// region rate beliefs
|
// region rate beliefs
|
||||||
|
@ -146,7 +146,7 @@ object CivilianUnitAutomation {
|
|||||||
private fun isLateGame(civ: Civilization): Boolean {
|
private fun isLateGame(civ: Civilization): Boolean {
|
||||||
val researchCompletePercent =
|
val researchCompletePercent =
|
||||||
(civ.tech.researchedTechnologies.size * 1.0f) / civ.gameInfo.ruleset.technologies.size
|
(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 */
|
/** Returns whether the civilian spends its turn hiding and not moving */
|
||||||
|
@ -677,7 +677,7 @@ class Civilization : IsPartOfGameInfoSerialization {
|
|||||||
else when (category) {
|
else when (category) {
|
||||||
RankingType.Score -> calculateTotalScore().toInt()
|
RankingType.Score -> calculateTotalScore().toInt()
|
||||||
RankingType.Population -> cities.sumOf { it.population.population }
|
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.Production -> stats.statsForNextTurn.production.roundToInt()
|
||||||
RankingType.Gold -> gold
|
RankingType.Gold -> gold
|
||||||
RankingType.Territory -> cities.sumOf { it.tiles.size }
|
RankingType.Territory -> cities.sumOf { it.tiles.size }
|
||||||
|
@ -12,7 +12,7 @@ enum class RankingType(
|
|||||||
// production, gold, happiness, and culture already have icons added when the line is `tr()`anslated
|
// 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'),
|
Score({ ImageGetter.getImage("OtherIcons/Score").apply { color = Color.FIREBRICK } }, 'S'),
|
||||||
Population({ ImageGetter.getStatIcon("Population") }, 'N'),
|
Population({ ImageGetter.getStatIcon("Population") }, 'N'),
|
||||||
CropYield("Crop Yield", { ImageGetter.getStatIcon("Food") }, 'C'),
|
Growth("Growth", { ImageGetter.getStatIcon("Food") }, 'C'),
|
||||||
Production('P'),
|
Production('P'),
|
||||||
Gold('G'),
|
Gold('G'),
|
||||||
Territory({ ImageGetter.getImage("OtherIcons/Hexagon") }, 'T'),
|
Territory({ ImageGetter.getImage("OtherIcons/Hexagon") }, 'T'),
|
||||||
|
Loading…
Reference in New Issue
Block a user