From c7652873335c4b9fb719340bca31efec9238d2ac Mon Sep 17 00:00:00 2001 From: yairm210 Date: Sun, 21 Jul 2024 11:37:16 +0300 Subject: [PATCH] Better state-based random - ensure repeatability while increasing diversity (less "bunching" of so-called "random" results) --- core/src/com/unciv/models/ruleset/unique/Conditionals.kt | 7 ++++++- .../unciv/models/ruleset/unique/StateForConditionals.kt | 8 ++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/core/src/com/unciv/models/ruleset/unique/Conditionals.kt b/core/src/com/unciv/models/ruleset/unique/Conditionals.kt index e890e52736..e14072608a 100644 --- a/core/src/com/unciv/models/ruleset/unique/Conditionals.kt +++ b/core/src/com/unciv/models/ruleset/unique/Conditionals.kt @@ -20,7 +20,12 @@ object Conditionals { if (conditional.type?.targetTypes?.any { it.modifierType == UniqueTarget.ModifierType.Other } == true) return true // not a filtering condition, includes e.g. ModifierHiddenFromUsers - val stateBasedRandom by lazy { Random(state.hashCode() * 31 + (state.gameInfo?.turns?.hashCode() ?: 0)) } + val stateBasedRandom by lazy { + var seed = state.gameInfo?.turns?.hashCode() ?: 0 + seed = seed * 31 + (unique?.hashCode() ?: 0) + seed = seed * 31 + state.hashCode() + Random(seed) + } /** Helper to simplify conditional tests requiring gameInfo */ fun checkOnGameInfo(predicate: (GameInfo.() -> Boolean)): Boolean { diff --git a/core/src/com/unciv/models/ruleset/unique/StateForConditionals.kt b/core/src/com/unciv/models/ruleset/unique/StateForConditionals.kt index 74da9c2387..adf718ce16 100644 --- a/core/src/com/unciv/models/ruleset/unique/StateForConditionals.kt +++ b/core/src/com/unciv/models/ruleset/unique/StateForConditionals.kt @@ -106,10 +106,10 @@ data class StateForConditionals( fun CombatAction?.hash() = this?.name?.hashCode() ?: 0 fun Region?.hash() = this?.rect?.hashCode() ?: 0 - var result = civInfo.hash() - result = 31 * result + city.hash() - result = 31 * result + unit.hash() - result = 31 * result + tile.hash() + var result = relevantCiv.hash() + result = 31 * result + relevantCity.hash() + result = 31 * result + relevantUnit.hash() + result = 31 * result + relevantTile.hash() result = 31 * result + ourCombatant.hash() result = 31 * result + theirCombatant.hash() result = 31 * result + attackedTile.hash()