From eb2f5c0be35d9b7f2aff0fd3da6104ba86d9cafb Mon Sep 17 00:00:00 2001 From: itanasi <44038014+itanasi@users.noreply.github.com> Date: Sun, 15 Dec 2024 21:37:26 -0800 Subject: [PATCH 1/7] Changes --- .../com/unciv/logic/simulation/Simulation.kt | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/core/src/com/unciv/logic/simulation/Simulation.kt b/core/src/com/unciv/logic/simulation/Simulation.kt index 181174e05cb0f..1a0293ba43d00 100644 --- a/core/src/com/unciv/logic/simulation/Simulation.kt +++ b/core/src/com/unciv/logic/simulation/Simulation.kt @@ -20,7 +20,8 @@ class Simulation( private val newGameInfo: GameInfo, val simulationsPerThread: Int = 1, private val threadsNumber: Int = 1, - private val maxTurns: Int = 500 + private val maxTurns: Int = 500, + private val statTurn: Int = 100 ) { private val maxSimulations = threadsNumber * simulationsPerThread val civilizations = newGameInfo.civilizations.filter { it.civName != Constants.spectator }.map { it.civName } @@ -28,6 +29,7 @@ class Simulation( private var startTime: Long = 0 var steps = ArrayList() var numWins = mutableMapOf() + var avgStat = mutableMapOf() private var winRateByVictory = HashMap>() private var winTurnByVictory = HashMap>() private var avgSpeed = 0f @@ -40,6 +42,7 @@ class Simulation( init{ for (civ in civilizations) { this.numWins[civ] = MutableInt(0) + this.avgStat[civ] = MutableInt(0) winRateByVictory[civ] = mutableMapOf() for (victory in UncivGame.Current.gameInfo!!.ruleset.victories.keys) winRateByVictory[civ]!![victory] = MutableInt(0) @@ -59,9 +62,13 @@ class Simulation( jobs.add(launch(CoroutineName("simulation-${threadId}")) { repeat(simulationsPerThread) { val gameInfo = GameStarter.startNewGame(GameSetupInfo(newGameInfo)) - gameInfo.simulateMaxTurns = maxTurns + gameInfo.simulateMaxTurns = statTurn gameInfo.simulateUntilWin = true gameInfo.nextTurn() + saveStat(gameInfo) + + gameInfo.simulateMaxTurns = maxTurns + gameInfo.nextTurn() val step = SimulationStep(gameInfo) @@ -92,6 +99,16 @@ class Simulation( println("Simulation step ($stepCounter/$maxSimulations)") } + @Synchronized + fun saveStat(gameInfo: GameInfo) { + for (civ in gameInfo.civilizations.filter { it.civName != Constants.spectator }) { + var popsum = 0 + civ.cities.forEach { city -> popsum += city.population.population } + //println("$civ $popsum") + avgStat[civ.civName]!!.set(avgStat[civ.civName]!!.get() + popsum) + } + } + @Synchronized fun print(){ getStats() @@ -149,6 +166,7 @@ class Simulation( outString += "$victory: $winsTurns " } outString += "avg turns\n" + outString += "avgStat (turn $statTurn): ${avgStat[civ]!!.value/numSteps}\n" } outString += "\nAverage speed: %.1f turns/s \n".format(avgSpeed) outString += "Average game duration: $avgDuration\n" From e706474ca3f3647eb01b9f2f603e1d4f4f27efa5 Mon Sep 17 00:00:00 2001 From: itanasi <44038014+itanasi@users.noreply.github.com> Date: Sun, 15 Dec 2024 21:41:13 -0800 Subject: [PATCH 2/7] Default to not using avgStat --- .../com/unciv/logic/simulation/Simulation.kt | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/core/src/com/unciv/logic/simulation/Simulation.kt b/core/src/com/unciv/logic/simulation/Simulation.kt index 1a0293ba43d00..e5f4c33f4c07d 100644 --- a/core/src/com/unciv/logic/simulation/Simulation.kt +++ b/core/src/com/unciv/logic/simulation/Simulation.kt @@ -21,7 +21,7 @@ class Simulation( val simulationsPerThread: Int = 1, private val threadsNumber: Int = 1, private val maxTurns: Int = 500, - private val statTurn: Int = 100 + private val statTurn: Int = -1 ) { private val maxSimulations = threadsNumber * simulationsPerThread val civilizations = newGameInfo.civilizations.filter { it.civName != Constants.spectator }.map { it.civName } @@ -62,13 +62,15 @@ class Simulation( jobs.add(launch(CoroutineName("simulation-${threadId}")) { repeat(simulationsPerThread) { val gameInfo = GameStarter.startNewGame(GameSetupInfo(newGameInfo)) - gameInfo.simulateMaxTurns = statTurn + gameInfo.simulateMaxTurns = if(statTurn == -1) maxTurns else statTurn gameInfo.simulateUntilWin = true gameInfo.nextTurn() - saveStat(gameInfo) - - gameInfo.simulateMaxTurns = maxTurns - gameInfo.nextTurn() + + if (statTurn != -1) { + saveStat(gameInfo) + gameInfo.simulateMaxTurns = maxTurns + gameInfo.nextTurn() + } val step = SimulationStep(gameInfo) @@ -166,7 +168,8 @@ class Simulation( outString += "$victory: $winsTurns " } outString += "avg turns\n" - outString += "avgStat (turn $statTurn): ${avgStat[civ]!!.value/numSteps}\n" + if (statTurn != -1) + outString += "avgStat (turn $statTurn): ${avgStat[civ]!!.value/numSteps}\n" } outString += "\nAverage speed: %.1f turns/s \n".format(avgSpeed) outString += "Average game duration: $avgDuration\n" From 1c48352d3d570b1b3fe9c3f8df13cf0e56cb6168 Mon Sep 17 00:00:00 2001 From: itanasi <44038014+itanasi@users.noreply.github.com> Date: Sun, 15 Dec 2024 22:38:48 -0800 Subject: [PATCH 3/7] Make print a float --- core/src/com/unciv/logic/simulation/Simulation.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/com/unciv/logic/simulation/Simulation.kt b/core/src/com/unciv/logic/simulation/Simulation.kt index e5f4c33f4c07d..7ac6f8584ff29 100644 --- a/core/src/com/unciv/logic/simulation/Simulation.kt +++ b/core/src/com/unciv/logic/simulation/Simulation.kt @@ -58,6 +58,7 @@ class Simulation( val jobs: ArrayList = ArrayList() println("Starting new game with major civs: "+newGameInfo.civilizations.filter { it.isMajorCiv() }.joinToString { it.civName } + " and minor civs: "+newGameInfo.civilizations.filter { it.isCityState }.joinToString { it.civName }) + newGameInfo.gameParameters.shufflePlayerOrder = true for (threadId in 1..threadsNumber) { jobs.add(launch(CoroutineName("simulation-${threadId}")) { repeat(simulationsPerThread) { @@ -169,7 +170,7 @@ class Simulation( } outString += "avg turns\n" if (statTurn != -1) - outString += "avgStat (turn $statTurn): ${avgStat[civ]!!.value/numSteps}\n" + outString += "avgStat (turn $statTurn): ${avgStat[civ]!!.value.toFloat()/numSteps}\n" } outString += "\nAverage speed: %.1f turns/s \n".format(avgSpeed) outString += "Average game duration: $avgDuration\n" From 5fba933ec9fcb04ce0a3e4bde9607d178364b84a Mon Sep 17 00:00:00 2001 From: itanasi <44038014+itanasi@users.noreply.github.com> Date: Sun, 15 Dec 2024 22:58:50 -0800 Subject: [PATCH 4/7] Make statTurns a list rename sumStat better summation for popsum --- .../com/unciv/logic/simulation/Simulation.kt | 33 +++++++++++-------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/core/src/com/unciv/logic/simulation/Simulation.kt b/core/src/com/unciv/logic/simulation/Simulation.kt index 7ac6f8584ff29..53c0575f79309 100644 --- a/core/src/com/unciv/logic/simulation/Simulation.kt +++ b/core/src/com/unciv/logic/simulation/Simulation.kt @@ -21,7 +21,7 @@ class Simulation( val simulationsPerThread: Int = 1, private val threadsNumber: Int = 1, private val maxTurns: Int = 500, - private val statTurn: Int = -1 + private val statTurns: List = listOf() ) { private val maxSimulations = threadsNumber * simulationsPerThread val civilizations = newGameInfo.civilizations.filter { it.civName != Constants.spectator }.map { it.civName } @@ -29,7 +29,7 @@ class Simulation( private var startTime: Long = 0 var steps = ArrayList() var numWins = mutableMapOf() - var avgStat = mutableMapOf() + var sumStat = mutableMapOf>() private var winRateByVictory = HashMap>() private var winTurnByVictory = HashMap>() private var avgSpeed = 0f @@ -42,7 +42,8 @@ class Simulation( init{ for (civ in civilizations) { this.numWins[civ] = MutableInt(0) - this.avgStat[civ] = MutableInt(0) + for (turn in statTurns) + this.sumStat.getOrPut(civ) { mutableMapOf() }[turn] = MutableInt(0) winRateByVictory[civ] = mutableMapOf() for (victory in UncivGame.Current.gameInfo!!.ruleset.victories.keys) winRateByVictory[civ]!![victory] = MutableInt(0) @@ -63,17 +64,23 @@ class Simulation( jobs.add(launch(CoroutineName("simulation-${threadId}")) { repeat(simulationsPerThread) { val gameInfo = GameStarter.startNewGame(GameSetupInfo(newGameInfo)) - gameInfo.simulateMaxTurns = if(statTurn == -1) maxTurns else statTurn gameInfo.simulateUntilWin = true - gameInfo.nextTurn() - - if (statTurn != -1) { + for (turn in statTurns) { + gameInfo.simulateMaxTurns = turn + gameInfo.nextTurn() saveStat(gameInfo) + val step = SimulationStep(gameInfo) + if (step.victoryType != null) + break + } + // check if Victory + var step = SimulationStep(gameInfo) + if (step.victoryType == null) { gameInfo.simulateMaxTurns = maxTurns gameInfo.nextTurn() } - val step = SimulationStep(gameInfo) + step = SimulationStep(gameInfo) // final game state if (step.victoryType != null) { step.winner = step.currentPlayer @@ -104,11 +111,11 @@ class Simulation( @Synchronized fun saveStat(gameInfo: GameInfo) { + val turn = gameInfo.turns for (civ in gameInfo.civilizations.filter { it.civName != Constants.spectator }) { - var popsum = 0 - civ.cities.forEach { city -> popsum += city.population.population } + val popsum = civ.cities.sumOf { it.population.population } //println("$civ $popsum") - avgStat[civ.civName]!!.set(avgStat[civ.civName]!!.get() + popsum) + sumStat[civ.civName]!![turn]!!.set(sumStat[civ.civName]!![turn]!!.get() + popsum) } } @@ -169,8 +176,8 @@ class Simulation( outString += "$victory: $winsTurns " } outString += "avg turns\n" - if (statTurn != -1) - outString += "avgStat (turn $statTurn): ${avgStat[civ]!!.value.toFloat()/numSteps}\n" + for (turn in statTurns) + outString += "avgStat (@$turn): ${sumStat[civ]!![turn]!!.value.toFloat()/numSteps}\n" } outString += "\nAverage speed: %.1f turns/s \n".format(avgSpeed) outString += "Average game duration: $avgDuration\n" From 10433544b8c50669c736dc9b3c69852e69f36589 Mon Sep 17 00:00:00 2001 From: itanasi <44038014+itanasi@users.noreply.github.com> Date: Sun, 15 Dec 2024 23:12:55 -0800 Subject: [PATCH 5/7] Fix potential nullpointer --- core/src/com/unciv/logic/simulation/Simulation.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/com/unciv/logic/simulation/Simulation.kt b/core/src/com/unciv/logic/simulation/Simulation.kt index 53c0575f79309..da19cbd3dcd3c 100644 --- a/core/src/com/unciv/logic/simulation/Simulation.kt +++ b/core/src/com/unciv/logic/simulation/Simulation.kt @@ -68,10 +68,10 @@ class Simulation( for (turn in statTurns) { gameInfo.simulateMaxTurns = turn gameInfo.nextTurn() - saveStat(gameInfo) val step = SimulationStep(gameInfo) if (step.victoryType != null) break + saveStat(gameInfo) } // check if Victory var step = SimulationStep(gameInfo) From 3d205b59a3b7f3081ae81dc92f2d96db61bfbbee Mon Sep 17 00:00:00 2001 From: itanasi <44038014+itanasi@users.noreply.github.com> Date: Sun, 15 Dec 2024 23:33:34 -0800 Subject: [PATCH 6/7] Add .add() --- core/src/com/unciv/logic/simulation/MutableInt.kt | 1 + core/src/com/unciv/logic/simulation/Simulation.kt | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/com/unciv/logic/simulation/MutableInt.kt b/core/src/com/unciv/logic/simulation/MutableInt.kt index b3a993ddc3c5e..5eac80e02f62b 100644 --- a/core/src/com/unciv/logic/simulation/MutableInt.kt +++ b/core/src/com/unciv/logic/simulation/MutableInt.kt @@ -6,6 +6,7 @@ class MutableInt(var value: Int = 0) { fun inc() { ++value } fun get(): Int { return value } fun set(newValue: Int) { value = newValue } + fun add(addend: Int) { value += addend } override fun toString(): String { return value.tr() diff --git a/core/src/com/unciv/logic/simulation/Simulation.kt b/core/src/com/unciv/logic/simulation/Simulation.kt index da19cbd3dcd3c..790d1f557770b 100644 --- a/core/src/com/unciv/logic/simulation/Simulation.kt +++ b/core/src/com/unciv/logic/simulation/Simulation.kt @@ -115,7 +115,7 @@ class Simulation( for (civ in gameInfo.civilizations.filter { it.civName != Constants.spectator }) { val popsum = civ.cities.sumOf { it.population.population } //println("$civ $popsum") - sumStat[civ.civName]!![turn]!!.set(sumStat[civ.civName]!![turn]!!.get() + popsum) + sumStat[civ.civName]!![turn]!!.add(popsum) } } From cb14beb6f18ef649828e6526b9c9f3e98c22a9e5 Mon Sep 17 00:00:00 2001 From: itanasi <44038014+itanasi@users.noreply.github.com> Date: Mon, 16 Dec 2024 00:03:01 -0800 Subject: [PATCH 7/7] And another place to use .add() --- core/src/com/unciv/logic/simulation/Simulation.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/com/unciv/logic/simulation/Simulation.kt b/core/src/com/unciv/logic/simulation/Simulation.kt index 790d1f557770b..614714facf3d4 100644 --- a/core/src/com/unciv/logic/simulation/Simulation.kt +++ b/core/src/com/unciv/logic/simulation/Simulation.kt @@ -134,7 +134,7 @@ class Simulation( if (it.winner != null) { numWins[it.winner!!]!!.inc() winRateByVictory[it.winner!!]!![it.victoryType]!!.inc() - winTurnByVictory[it.winner!!]!![it.victoryType]!!.set(winTurnByVictory[it.winner!!]!![it.victoryType]!!.get() + it.turns) + winTurnByVictory[it.winner!!]!![it.victoryType]!!.add(it.turns) } } totalTurns = steps.sumOf { it.turns }