From a6ba428518856f1d5d2855ff5ac0a13f44319120 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Tue, 11 Mar 2025 16:56:51 +0700 Subject: [PATCH] Remove custom random generators except for gjrand64 which is used for worldgen --- .../mc/otm/core/util/CMWCRandom.kt | 117 ------------------ .../mc/otm/core/util/LCG64RandomSource.kt | 59 --------- .../mc/otm/core/util/PCG32RandomSource.kt | 51 -------- .../mc/otm/core/util/Xoshiro256Random.kt | 93 -------------- 4 files changed, 320 deletions(-) delete mode 100644 src/main/kotlin/ru/dbotthepony/mc/otm/core/util/CMWCRandom.kt delete mode 100644 src/main/kotlin/ru/dbotthepony/mc/otm/core/util/LCG64RandomSource.kt delete mode 100644 src/main/kotlin/ru/dbotthepony/mc/otm/core/util/PCG32RandomSource.kt delete mode 100644 src/main/kotlin/ru/dbotthepony/mc/otm/core/util/Xoshiro256Random.kt diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/CMWCRandom.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/CMWCRandom.kt deleted file mode 100644 index 16225f78f..000000000 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/CMWCRandom.kt +++ /dev/null @@ -1,117 +0,0 @@ -package ru.dbotthepony.mc.otm.core.util - -import net.minecraft.util.Mth -import net.minecraft.util.RandomSource -import net.minecraft.world.level.levelgen.MarsagliaPolarGaussian -import net.minecraft.world.level.levelgen.PositionalRandomFactory -import net.minecraft.world.level.levelgen.RandomSupport -import ru.dbotthepony.kommons.random.PCG32Random -import java.lang.StringBuilder -import java.util.random.RandomGenerator - -/** - * Random number generator with insane period of at least 2^511 - */ -class CMWCRandom(seed: Long = RandomSupport.generateUniqueSeed()) : RandomGenerator, RandomSource { - private val state = IntArray(CMWC_STATE_SIZE) - private var carry = 0 - private var stateIndex = 0 - private val gaussian = MarsagliaPolarGaussian(this) - - init { - setSeed(seed) - } - - override fun setSeed(seed: Long) { - val rng = PCG32Random(seed) - - // init state with regular LCG produced values - for (i in 1 until state.size) { - state[i] = rng.nextInt() - } - - do { - carry = rng.nextInt() - } while(carry !in 0 until CMWC_CARRY_MAX) - - stateIndex = state.size - 1 - gaussian.reset() - } - - override fun nextInt(): Int { - stateIndex = (stateIndex + 1).and(CMWC_STATE_SIZE - 1) - val t = 18782L * state[stateIndex] + carry - - carry = t.ushr(32).toInt() - var x = t.toInt() + carry - - if (x < carry) { - x++ - carry++ - } - - state[stateIndex] = 0xfffffffe.toInt() - x - return state[stateIndex] - } - - override fun nextLong(): Long { - val a = nextInt().toLong() and 0xFFFFFFFFL - val b = nextInt().toLong() and 0xFFFFFFFFL - return a.shl(32) or b - } - - override fun nextInt(bound: Int): Int { - return super.nextInt(bound) - } - - override fun nextInt(origin: Int, bound: Int): Int { - return super.nextInt(origin, bound) - } - - override fun nextBoolean(): Boolean { - return super.nextBoolean() - } - - override fun nextFloat(): Float { - return super.nextFloat() - } - - override fun nextDouble(): Double { - return super.nextDouble() - } - - override fun nextGaussian(): Double { - return gaussian.nextGaussian() - } - - override fun fork(): RandomSource { - return CMWCRandom(nextLong()) - } - - override fun forkPositional(): PositionalRandomFactory { - return Positional(nextLong()) - } - - class Positional(private val seed: Long) : PositionalRandomFactory { - override fun at(x: Int, y: Int, z: Int): RandomSource { - return CMWCRandom(Mth.getSeed(x, y, z).xor(seed)) - } - - override fun fromHashOf(name: String): RandomSource { - return CMWCRandom(name.hashCode().toLong().xor(seed)) - } - - override fun fromSeed(seed: Long): RandomSource { - return CMWCRandom(seed) - } - - override fun parityConfigString(builder: StringBuilder) { - throw UnsupportedOperationException() - } - } - - companion object { - const val CMWC_STATE_SIZE = 32 // 4096 - const val CMWC_CARRY_MAX = 809430660 - } -} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/LCG64RandomSource.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/LCG64RandomSource.kt deleted file mode 100644 index 849e38e87..000000000 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/LCG64RandomSource.kt +++ /dev/null @@ -1,59 +0,0 @@ -package ru.dbotthepony.mc.otm.core.util - -import net.minecraft.util.Mth -import net.minecraft.util.RandomSource -import net.minecraft.world.level.levelgen.LegacyRandomSource -import net.minecraft.world.level.levelgen.MarsagliaPolarGaussian -import net.minecraft.world.level.levelgen.PositionalRandomFactory -import net.minecraft.world.level.levelgen.RandomSupport -import ru.dbotthepony.kommons.random.LCG64Random -import java.lang.StringBuilder - -/** - * Simple and insanely fast random number generator, which can be used for seeding (initializing internal state) of other number generators. - * - * While can be used on its own, it probably shouldn't. - * - * Differs from [LegacyRandomSource] (also LCG, created by [RandomSource.create]) Minecraft uses in: - * * Different constants (with supposedly/expected better statistical properties) - * * Always use upper 32 bits instead of implementing BitRandomSource and sampling some upper bits - * * Uses all bits from provided seed - */ -class LCG64RandomSource(seed: Long = RandomSupport.generateUniqueSeed()) : LCG64Random(seed), IRandomSourceGenerator { - private val gaussian = MarsagliaPolarGaussian(this) - - override fun setSeed(seed: Long) { - this.seed = seed - gaussian.reset() - } - - override fun nextGaussian(): Double { - return gaussian.nextGaussian() - } - - override fun fork(): RandomSource { - return LCG64RandomSource(nextLong()) - } - - override fun forkPositional(): PositionalRandomFactory { - return Positional(nextLong()) - } - - class Positional(private val seed: Long) : PositionalRandomFactory { - override fun at(x: Int, y: Int, z: Int): RandomSource { - return LCG64RandomSource(Mth.getSeed(x, y, z).xor(seed)) - } - - override fun fromHashOf(name: String): RandomSource { - return LCG64RandomSource(name.hashCode().toLong().xor(seed)) - } - - override fun fromSeed(seed: Long): RandomSource { - return LCG64RandomSource(seed) - } - - override fun parityConfigString(builder: StringBuilder) { - throw UnsupportedOperationException() - } - } -} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/PCG32RandomSource.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/PCG32RandomSource.kt deleted file mode 100644 index ae2f74205..000000000 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/PCG32RandomSource.kt +++ /dev/null @@ -1,51 +0,0 @@ -package ru.dbotthepony.mc.otm.core.util - -import net.minecraft.util.Mth -import net.minecraft.util.RandomSource -import net.minecraft.world.level.levelgen.MarsagliaPolarGaussian -import net.minecraft.world.level.levelgen.PositionalRandomFactory -import net.minecraft.world.level.levelgen.RandomSupport -import ru.dbotthepony.kommons.random.PCG32Random -import java.lang.StringBuilder - -/** - * @see PCG32Random - */ -class PCG32RandomSource(seed: Long = RandomSupport.generateUniqueSeed()) : PCG32Random(seed), IRandomSourceGenerator { - private val gaussian = MarsagliaPolarGaussian(this) - - override fun setSeed(seed: Long) { - this.seed = seed - gaussian.reset() - } - - override fun nextGaussian(): Double { - return gaussian.nextGaussian() - } - - override fun fork(): RandomSource { - return PCG32RandomSource(nextLong()) - } - - override fun forkPositional(): PositionalRandomFactory { - return Positional(nextLong()) - } - - class Positional(private val seed: Long) : PositionalRandomFactory { - override fun at(x: Int, y: Int, z: Int): RandomSource { - return PCG32RandomSource(Mth.getSeed(x, y, z).xor(seed)) - } - - override fun fromHashOf(name: String): RandomSource { - return PCG32RandomSource(name.hashCode().toLong().xor(seed)) - } - - override fun fromSeed(seed: Long): RandomSource { - return PCG32RandomSource(seed) - } - - override fun parityConfigString(builder: StringBuilder) { - throw UnsupportedOperationException() - } - } -} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/Xoshiro256Random.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/Xoshiro256Random.kt deleted file mode 100644 index 133762f55..000000000 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/Xoshiro256Random.kt +++ /dev/null @@ -1,93 +0,0 @@ -package ru.dbotthepony.mc.otm.core.util - -import it.unimi.dsi.fastutil.HashCommon -import net.minecraft.util.Mth -import net.minecraft.util.RandomSource -import net.minecraft.world.level.levelgen.MarsagliaPolarGaussian -import net.minecraft.world.level.levelgen.PositionalRandomFactory -import net.minecraft.world.level.levelgen.RandomSupport -import ru.dbotthepony.kommons.random.LCG64Random -import ru.dbotthepony.kommons.random.Xoshiro256StarStarRandom - -/** - * Excellent number generator with guaranteed period of 2^255 - */ -class Xoshiro256Random : Xoshiro256StarStarRandom, IRandomSourceGenerator { - private val gaussian = MarsagliaPolarGaussian(this) - - // raw - private constructor(s0: Long, s1: Long, s2: Long, s3: Long, marker: Nothing?): super(s0, s1, s2, s3, null) - // normal - constructor(s0: Long, s1: Long, s2: Long, s3: Long) : super(s0, s1, s2, s3) - - // 64-bit seeded - constructor(seed: Long) : super(1L, 2L, 3L, 4L, null) { - setSeed(seed) - } - - // completely random - constructor() : super(RandomSupport.generateUniqueSeed(), RandomSupport.generateUniqueSeed(), RandomSupport.generateUniqueSeed(), RandomSupport.generateUniqueSeed(), null) - - override fun setSeed(seed: Long) { - val rng = LCG64Random(seed) - s0 = rng.nextLong() - s1 = rng.nextLong() - s2 = rng.nextLong() - s3 = rng.nextLong() - gaussian.reset() - } - - override fun nextInt(): Int { - // sample upper bits - return nextLong().ushr(32).toInt() - } - - override fun nextGaussian(): Double { - return gaussian.nextGaussian() - } - - override fun fork(): RandomSource { - return Xoshiro256Random(nextLong(), nextLong(), nextLong(), nextLong(), null) - } - - override fun forkPositional(): PositionalRandomFactory { - return Positional(nextLong(), nextLong(), nextLong(), nextLong()) - } - - class Positional( - private val s0: Long, - private val s1: Long, - private val s2: Long, - private val s3: Long, - ) : PositionalRandomFactory { - override fun at(x: Int, y: Int, z: Int): RandomSource { - val rng = LCG64RandomSource(Mth.getSeed(x, y, z)) - - return Xoshiro256Random( - s0.rotateLeft(11).xor(rng.nextLong()), - s1.rotateLeft(22).xor(rng.nextLong()), - s2.rotateLeft(33).xor(rng.nextLong()), - s3.rotateLeft(44).xor(rng.nextLong()), - ) - } - - override fun fromHashOf(name: String): RandomSource { - return Xoshiro256Random(s0, HashCommon.murmurHash3(name.hashCode().toLong()).xor(s1), s2, s3) - } - - override fun fromSeed(seed: Long): RandomSource { - return Xoshiro256Random(seed) - } - - override fun parityConfigString(builder: StringBuilder) { - throw UnsupportedOperationException() - } - } - - companion object { - @JvmStatic - fun raw(s0: Long, s1: Long, s2: Long, s3: Long): Xoshiro256Random { - return Xoshiro256Random(s0, s1, s2, s3, null) - } - } -}