From d273586a3dba3c56cc4ecf17192871b603f4d390 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Fri, 21 Mar 2025 13:41:58 +0700 Subject: [PATCH] Provide a way to properly inherit random generators by separating cranking/round from main function --- gradle.properties | 2 +- .../dbotthepony/kommons/random/GJRAND64Random.kt | 10 +++++++--- .../ru/dbotthepony/kommons/random/JSF32Random.kt | 8 ++++++-- .../ru/dbotthepony/kommons/random/JSF64Random.kt | 8 ++++++-- .../ru/dbotthepony/kommons/random/LCG64Random.kt | 8 ++++++-- .../ru/dbotthepony/kommons/random/PCG32Random.kt | 6 +++++- .../ru/dbotthepony/kommons/random/ShishuaRandom.kt | 6 +++++- .../ru/dbotthepony/kommons/random/WOB2MRandom.kt | 14 +++++++++++--- .../kommons/random/Xoshiro256PlusPlusRandom.kt | 8 ++++++-- .../kommons/random/Xoshiro256StarStarRandom.kt | 8 ++++++-- 10 files changed, 59 insertions(+), 19 deletions(-) diff --git a/gradle.properties b/gradle.properties index 3763027..0c83731 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,7 +4,7 @@ kotlin.code.style=official specifyKotlinAsDependency=false projectGroup=ru.dbotthepony.kommons -projectVersion=3.7.0 +projectVersion=3.8.0 guavaDepVersion=33.0.0 gsonDepVersion=2.8.9 diff --git a/src/main/kotlin/ru/dbotthepony/kommons/random/GJRAND64Random.kt b/src/main/kotlin/ru/dbotthepony/kommons/random/GJRAND64Random.kt index bf304d8..a1d33c5 100644 --- a/src/main/kotlin/ru/dbotthepony/kommons/random/GJRAND64Random.kt +++ b/src/main/kotlin/ru/dbotthepony/kommons/random/GJRAND64Random.kt @@ -23,7 +23,7 @@ open class GJRAND64Random protected constructor( ) : RandomGenerator { constructor(seed0: Long, seed1: Long) : this(seed0, seed1, SEED2_INIT, SEED3_INIT, null) { for (i in 0 until 14) - nextLong() + round() } constructor(seed: Long) : this(seed, 0L) @@ -39,10 +39,10 @@ open class GJRAND64Random protected constructor( s3 = SEED3_INIT for (i in 0 until 14) - nextLong() + round() } - final override fun nextLong(): Long { + protected fun round(): Long { s1 += s2 s0 = s0.rotateLeft(32) s2 = s2 xor s1 @@ -57,6 +57,10 @@ open class GJRAND64Random protected constructor( return s0 } + override fun nextLong(): Long { + return round() + } + companion object { const val SEED2_INIT = 2000001L const val SEED3_INIT = 0L diff --git a/src/main/kotlin/ru/dbotthepony/kommons/random/JSF32Random.kt b/src/main/kotlin/ru/dbotthepony/kommons/random/JSF32Random.kt index 753d936..ffda6e2 100644 --- a/src/main/kotlin/ru/dbotthepony/kommons/random/JSF32Random.kt +++ b/src/main/kotlin/ru/dbotthepony/kommons/random/JSF32Random.kt @@ -30,10 +30,10 @@ open class JSF32Random protected constructor( */ constructor(seed: Int) : this(SEED0_INIT, seed, seed, seed, null) { for (i in 0 until 20) - nextInt() + round() } - final override fun nextInt(): Int { + protected fun round(): Int { val e = s0 - s1.rotateLeft(27) s0 = s1 xor s2.rotateLeft(17) s1 = s2 + s3 @@ -42,6 +42,10 @@ open class JSF32Random protected constructor( return s3 } + override fun nextInt(): Int { + return round() + } + override fun nextLong(): Long { val a = nextInt().toLong() val b = nextInt().toLong() and 0xFFFFFFFFL diff --git a/src/main/kotlin/ru/dbotthepony/kommons/random/JSF64Random.kt b/src/main/kotlin/ru/dbotthepony/kommons/random/JSF64Random.kt index e0146b3..8dae01d 100644 --- a/src/main/kotlin/ru/dbotthepony/kommons/random/JSF64Random.kt +++ b/src/main/kotlin/ru/dbotthepony/kommons/random/JSF64Random.kt @@ -35,10 +35,10 @@ open class JSF64Random( */ constructor(seed: Long) : this(SEED0_INIT, seed, seed, seed, null) { for (i in 0 until 20) - nextLong() + round() } - final override fun nextLong(): Long { + protected fun round(): Long { val e = s0 - s1.rotateLeft(7) s0 = s1 xor s2.rotateLeft(13) s1 = s2 + s3.rotateLeft(37) @@ -47,6 +47,10 @@ open class JSF64Random( return s3 } + override fun nextLong(): Long { + return round() + } + companion object { const val SEED0_INIT = 0xf1ea5eedL } diff --git a/src/main/kotlin/ru/dbotthepony/kommons/random/LCG64Random.kt b/src/main/kotlin/ru/dbotthepony/kommons/random/LCG64Random.kt index cddda09..15d38e3 100644 --- a/src/main/kotlin/ru/dbotthepony/kommons/random/LCG64Random.kt +++ b/src/main/kotlin/ru/dbotthepony/kommons/random/LCG64Random.kt @@ -15,6 +15,11 @@ open class LCG64Random( @JvmField protected var seed: Long ) : RandomGenerator { + protected fun round(): Int { + this.seed = MULTIPLIER * this.seed + INCREMENT + return this.seed.ushr(32).toInt() + } + override fun nextLong(): Long { val a = nextInt().toLong() val b = nextInt().toLong() and 0xFFFFFFFFL @@ -22,8 +27,7 @@ open class LCG64Random( } override fun nextInt(): Int { - this.seed = MULTIPLIER * this.seed + INCREMENT - return this.seed.ushr(32).toInt() + return round() } companion object { diff --git a/src/main/kotlin/ru/dbotthepony/kommons/random/PCG32Random.kt b/src/main/kotlin/ru/dbotthepony/kommons/random/PCG32Random.kt index 4a3b744..79feff1 100644 --- a/src/main/kotlin/ru/dbotthepony/kommons/random/PCG32Random.kt +++ b/src/main/kotlin/ru/dbotthepony/kommons/random/PCG32Random.kt @@ -10,7 +10,7 @@ open class PCG32Random( @JvmField protected var seed: Long ) : RandomGenerator { - final override fun nextInt(): Int { + protected fun round(): Int { var x = this.seed this.seed = LCG64Random.MULTIPLIER * this.seed + LCG64Random.INCREMENT @@ -19,6 +19,10 @@ open class PCG32Random( return x.ushr(27).toInt().rotateLeft(rot.toInt()) } + override fun nextInt(): Int { + return round() + } + override fun nextLong(): Long { val a = nextInt().toLong() val b = nextInt().toLong() and 0xFFFFFFFFL diff --git a/src/main/kotlin/ru/dbotthepony/kommons/random/ShishuaRandom.kt b/src/main/kotlin/ru/dbotthepony/kommons/random/ShishuaRandom.kt index 1f358f7..c01c80b 100644 --- a/src/main/kotlin/ru/dbotthepony/kommons/random/ShishuaRandom.kt +++ b/src/main/kotlin/ru/dbotthepony/kommons/random/ShishuaRandom.kt @@ -27,7 +27,7 @@ open class ShishuaRandom() : RandomGenerator { engine.initialize(longArrayOf(rng.nextLong(), rng.nextLong(), rng.nextLong(), rng.nextLong())) } - final override fun nextLong(): Long { + protected fun round(): Long { if (index == 16) { index = 0 engine.step(acceptor, 1) @@ -35,4 +35,8 @@ open class ShishuaRandom() : RandomGenerator { return values[index++] } + + override fun nextLong(): Long { + return round() + } } diff --git a/src/main/kotlin/ru/dbotthepony/kommons/random/WOB2MRandom.kt b/src/main/kotlin/ru/dbotthepony/kommons/random/WOB2MRandom.kt index 73f8d77..0c3bf7b 100644 --- a/src/main/kotlin/ru/dbotthepony/kommons/random/WOB2MRandom.kt +++ b/src/main/kotlin/ru/dbotthepony/kommons/random/WOB2MRandom.kt @@ -34,20 +34,28 @@ open class WOB2MRandom protected constructor( ) : RandomGenerator { constructor(seed0: Long, seed1: Long) : this(seed0, seed1, Long.MIN_VALUE + 10, null) { for (i in 0 until 10) - nextLong() + round() } - final override fun nextLong(): Long { + protected fun round(): Long { val temp = seed0 + count++ seed0 = seed1 + temp.rotateLeft(12) seed1 = (0x0581af43eb71d8b3 * temp) xor seed0.rotateLeft(28) return seed1 } - fun previousLong(): Long { + override fun nextLong(): Long { + return round() + } + + protected fun previousRound(): Long { val temp = 0x6cc3621b095c967b * (seed1 xor seed0.rotateLeft(28)) seed1 = seed0 - temp.rotateLeft(12) seed0 = temp - --count return seed1 } + + open fun previousLong(): Long { + return previousRound() + } } diff --git a/src/main/kotlin/ru/dbotthepony/kommons/random/Xoshiro256PlusPlusRandom.kt b/src/main/kotlin/ru/dbotthepony/kommons/random/Xoshiro256PlusPlusRandom.kt index 31d6340..0402738 100644 --- a/src/main/kotlin/ru/dbotthepony/kommons/random/Xoshiro256PlusPlusRandom.kt +++ b/src/main/kotlin/ru/dbotthepony/kommons/random/Xoshiro256PlusPlusRandom.kt @@ -30,7 +30,7 @@ open class Xoshiro256PlusPlusRandom protected constructor( constructor(s0: Long, s1: Long, s2: Long, s3: Long) : this(s0, s1, s2, s3, null) { // discard some values so generator can get going if provided seed was "weak" for (i in 0 until 32) - nextLong() + round() } constructor(seed: Long) : this(1L, 0L, 0L, 0L, null) { @@ -41,7 +41,7 @@ open class Xoshiro256PlusPlusRandom protected constructor( s3 = rng.nextLong() } - final override fun nextLong(): Long { + protected fun round(): Long { val result = (s0 + s3).rotateLeft(23) + s1 val t = s1.shl(17) s2 = s2.xor(s0) @@ -53,6 +53,10 @@ open class Xoshiro256PlusPlusRandom protected constructor( return result } + override fun nextLong(): Long { + return round() + } + companion object { @JvmStatic fun raw( diff --git a/src/main/kotlin/ru/dbotthepony/kommons/random/Xoshiro256StarStarRandom.kt b/src/main/kotlin/ru/dbotthepony/kommons/random/Xoshiro256StarStarRandom.kt index 8512bf8..1715eb7 100644 --- a/src/main/kotlin/ru/dbotthepony/kommons/random/Xoshiro256StarStarRandom.kt +++ b/src/main/kotlin/ru/dbotthepony/kommons/random/Xoshiro256StarStarRandom.kt @@ -30,7 +30,7 @@ open class Xoshiro256StarStarRandom protected constructor( constructor(s0: Long, s1: Long, s2: Long, s3: Long) : this(s0, s1, s2, s3, null) { // discard some values so generator can get going if provided seed was "weak" for (i in 0 until 32) - nextLong() + round() } constructor(seed: Long) : this(1L, 0L, 0L, 0L, null) { @@ -41,7 +41,7 @@ open class Xoshiro256StarStarRandom protected constructor( s3 = rng.nextLong() } - final override fun nextLong(): Long { + protected fun round(): Long { val result = (s1 * 5).rotateLeft(7) * 9 val t = s1.shl(17) s2 = s2.xor(s0) @@ -53,6 +53,10 @@ open class Xoshiro256StarStarRandom protected constructor( return result } + override fun nextLong(): Long { + return round() + } + companion object { @JvmStatic fun raw(