Remove custom random generators except for gjrand64 which is used for worldgen

This commit is contained in:
DBotThePony 2025-03-11 16:56:51 +07:00
parent 5a016bef1b
commit a6ba428518
Signed by: DBot
GPG Key ID: DCC23B5715498507
4 changed files with 0 additions and 320 deletions

View File

@ -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<RandomGenerator>.nextInt(bound)
}
override fun nextInt(origin: Int, bound: Int): Int {
return super<RandomGenerator>.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
}
}

View File

@ -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()
}
}
}

View File

@ -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()
}
}
}

View File

@ -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)
}
}
}