More unit unique tests (#9639)

This commit is contained in:
Xander Lenstra
2023-06-25 08:35:31 +02:00
committed by GitHub
parent bc3f1341e1
commit aa0fb9ed8b
6 changed files with 68 additions and 7 deletions

View File

@ -358,7 +358,7 @@
"favoredReligion": "Hinduism",
"uniqueName": "Population Growth",
"uniques": ["Unhappiness from number of Cities doubled", "[-50]% Unhappiness from [Population] [in all cities]"],
"uniques": ["[+100]% unhappiness from the number of Cities", "[-50]% Unhappiness from [Population] [in all cities]"],
"cities": ["Delhi","Mumbai","Vijayanagara","Pataliputra","Varanasi","Agra","Calcutta","Lahore","Bangalore","Hyderabad","Madurai","Ahmedabad",
"Kolhapur","Prayaga","Ayodhya","Indraprastha","Mathura","Ujjain","Gulbarga","Jaunpur","Rajagriha","Sravasti","Tiruchirapalli","Thanjavur",
"Bodhgaya","Kushinagar","Amaravati","Gaur","Gwalior","Jaipur","Karachi"],
@ -976,7 +976,7 @@
"cities": ["Edinburgh","Dublin","Cardiff","Truro","Nantes","Douglas","Glasgow","Cork","Aberystwyth",
"Penzance","Rennes","Ramsey","Inverness","Limerick","Swansea","St. Ives","Brest","Peel","Aberdeen",
"Belfast","Caernarfon","Newquay","Saint-Nazaire","Castletown","Stirling","Galway","Conwy",
"St. Austell","Saint-Malo","Onchan","Dundee","Londonderry","Llanfairpwllgwyngyll","Falmouth","Lorient"]
"St. Austell","Saint-Malo","Onchan","Dundee","Londonderry","Llanfairpwllgwyngyll","Falmouth","Lorient"],
// Llanfairpwllgwyngyll should actually be Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch
"spyNames": ["Crìsdean", "Siobhán", "Seamus", "Ffion", "Pádraig", "Deirdre", "Mr. Quinn", "Éadaoin", "Alwyn", "Col Ceathar"]
},

View File

@ -331,7 +331,7 @@
"innerColor": [255, 163, 71],
"uniqueName": "Population Growth",
"uniques": ["Unhappiness from number of Cities doubled", "[-50]% Unhappiness from [Population] [in all cities]"],
"uniques": ["[+100]% unhappiness from the number of Cities", "[-50]% Unhappiness from [Population] [in all cities]"],
"cities": ["Delhi","Mumbai","Vijayanagara","Pataliputra","Varanasi","Agra","Calcutta","Lahore","Bangalore","Hyderabad","Madurai","Ahmedabad",
"Kolhapur","Prayaga","Ayodhya","Indraprastha","Mathura","Ujjain","Gulbarga","Jaunpur","Rajagriha","Sravasti","Tiruchirapalli","Thanjavur",
"Bodhgaya","Kushinagar","Amaravati","Gaur","Gwalior","Jaipur","Karachi"]

View File

@ -384,6 +384,14 @@ class CityStats(val city: City) {
fun updateCityHappiness(statsFromBuildings: StatTreeNode) {
val civInfo = city.civ
val newHappinessList = LinkedHashMap<String, Float>()
// This calculation seems weird to me.
// Suppose we calculate the modifier for an AI (non-human) player when the game settings has difficulty level 'prince'.
// We first get the difficulty modifier for this civilization, which results in the 'chieftain' modifier (0.6) being used,
// as this is a non-human player. Then we multiply that by the ai modifier in general, which is 1.0 for prince.
// The end result happens to be 0.6, which seems correct. However, if we were playing on chieftain difficulty,
// we would get back 0.6 twice and the modifier would be 0.36. Thus, in general there seems to be something wrong here
// I don't know enough about the original whether they do something similar or not and can't be bothered to find where
// in the source code this calculation takes place, but it would surprise me if they also did this double multiplication thing. ~xlenstra
var unhappinessModifier = civInfo.getDifficulty().unhappinessModifier
if (!civInfo.isHuman())
unhappinessModifier *= civInfo.gameInfo.getDifficulty().aiUnhappinessModifier
@ -394,7 +402,11 @@ class CityStats(val city: City) {
if (civInfo.hasUnique(UniqueType.UnhappinessFromCitiesDoubled))
unhappinessFromCity *= 2f //doubled for the Indian
newHappinessList["Cities"] = unhappinessFromCity * unhappinessModifier
var uniqueUnhappinessModifier = 0f
for (unique in civInfo.getMatchingUniques(UniqueType.UnhappinessFromCitiesPercentage))
uniqueUnhappinessModifier += unique.params[0].toFloat()
newHappinessList["Cities"] = unhappinessFromCity * unhappinessModifier * uniqueUnhappinessModifier.toPercent()
var unhappinessFromCitizens = city.population.population.toFloat()

View File

@ -156,11 +156,16 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags:
FoodConsumptionBySpecialists("[relativeAmount]% Food consumption by specialists [cityFilter]", UniqueTarget.Global, UniqueTarget.FollowerBelief),
/// Happiness
@Deprecated("As of 4.7.3", ReplaceWith("[+100]% unhappiness from the number of cities"))
UnhappinessFromCitiesDoubled("Unhappiness from number of Cities doubled", UniqueTarget.Global),
UnhappinessFromCitiesPercentage("[relativeAmount]% unhappiness from the number of cities", UniqueTarget.Global),
// Todo: capitalization of 'Unhappiness' -> 'unhappiness'
UnhappinessFromPopulationTypePercentageChange("[relativeAmount]% Unhappiness from [populationFilter] [cityFilter]", UniqueTarget.Global, UniqueTarget.FollowerBelief),
ExcessHappinessToGlobalStat("[relativeAmount]% of excess happiness converted to [stat]", UniqueTarget.Global),
RetainHappinessFromLuxury("Retain [relativeAmount]% of the happiness from a luxury after the last copy has been traded away", UniqueTarget.Global),
BonusHappinessFromLuxury("[amount] Happiness from each type of luxury resource", UniqueTarget.Global),
// Todo: capitalization of 'happiness' -> 'Happiness'
RetainHappinessFromLuxury("Retain [relativeAmount]% of the happiness from a luxury after the last copy has been traded away", UniqueTarget.Global),
// Todo: capitalization of 'happiness' -> 'Happiness'
ExcessHappinessToGlobalStat("[relativeAmount]% of excess happiness converted to [stat]", UniqueTarget.Global),
/// Unit Production
CannotBuildUnits("Cannot build [baseUnitFilter] units", UniqueTarget.Global),

View File

@ -7,16 +7,17 @@ import com.unciv.logic.map.tile.RoadStatus
import com.unciv.models.ruleset.BeliefType
import com.unciv.models.stats.Stats
import com.unciv.testing.GdxTestRunner
import com.unciv.ui.screens.worldscreen.unit.actions.UnitActionsPillage
import org.junit.Assert
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import kotlin.math.abs
@RunWith(GdxTestRunner::class)
class GlobalUniquesTests {
private lateinit var game: TestGame
private val epsilon = 0.01 // for float comparisons
@Before
fun initTheWorld() {
@ -571,6 +572,48 @@ class GlobalUniquesTests {
// endregion growth
// region happiness
@Test
fun unhappinessFromCitiesPercentageTest() {
val civInfo = game.addCiv("[+100]% unhappiness from the number of cities")
val tile = game.setTileFeatures(Vector2(0f,0f), Constants.desert)
val cityInfo = game.addCity(civInfo, tile, true)
cityInfo.cityStats.update()
// Because of some weird design choices, -3.6 is correct, though I would expect it to be -6 instead.
// As I'm not certain enough in my feeling that it should be -6, I'm changing the test to fit the code instead of the other way around.
// I've also written some text about this in CityStats.updateCityHappiness(). ~xlenstra
println(cityInfo.cityStats.happinessList)
Assert.assertTrue(abs(cityInfo.cityStats.happinessList["Cities"]!! - -3.6f) < epsilon) // Float rounding errors
}
@Test
fun unhappinessFromPopulationTypePercentageChangeTest() {
val civInfo = game.addCiv("[-50]% Unhappiness from [Population] [in all cities]")
val tile = game.setTileFeatures(Vector2(0f,0f), Constants.desert)
val cityInfo = game.addCity(civInfo, tile, true, initialPopulation = 4)
cityInfo.cityStats.update()
// This test suffers from the same problems as `unhappinessFromCitiesPercentageTest()`.
// This should be -2, I believe, as every pop should add -1 happiness and 4 pop with -50% unhappiness = -2 unhappiness.
println(cityInfo.cityStats.happinessList)
Assert.assertTrue(abs(cityInfo.cityStats.happinessList["Population"]!! - -1.2f) < epsilon)
val building = game.createBuilding("[-50]% Unhappiness from [Specialists] [in all cities]")
val specialist = game.createSpecialist()
building.specialistSlots[specialist] = 2
cityInfo.population.specialistAllocations[specialist] = 2
cityInfo.cityConstructions.addBuilding(building.name)
cityInfo.cityStats.update()
println(cityInfo.cityStats.happinessList)
// This test suffers from the same problems as above. It should be -1, I believe.
Assert.assertTrue(abs(cityInfo.cityStats.happinessList["Population"]!! - -0.6f) < epsilon)
}
// endregion happiness
// region Great Persons

View File

@ -49,6 +49,7 @@ class TestGame {
RulesetCache.loadRulesets(noMods = true)
ruleset = RulesetCache[BaseRuleset.Civ_V_GnK.fullName]!!
gameInfo.ruleset = ruleset
gameInfo.difficulty = "Prince"
gameInfo.difficultyObject = ruleset.difficulties["Prince"]!!
gameInfo.speed = ruleset.speeds[Speed.DEFAULTFORSIMULATION]!!
gameInfo.currentPlayerCiv = Civilization() // Will be uninitialized, do not build on for tests