Provide LCG64 implementation as separate class
This commit is contained in:
parent
d326e45b32
commit
e03d9b1a74
@ -22,17 +22,15 @@ class CMWCRandom(seed: Long = System.nanoTime()) : RandomGenerator, RandomSource
|
||||
|
||||
override fun setSeed(seed: Long) {
|
||||
this.seed = seed
|
||||
var lcg = seed
|
||||
val rng = LCG64Random(seed)
|
||||
|
||||
// init state with regular LCG produced values
|
||||
for (i in 1 until state.size) {
|
||||
lcg = lcg * 6364136223846793005 + 1442695040888963407
|
||||
state[i] = lcg.ushr(32).toInt()
|
||||
state[i] = rng.nextInt()
|
||||
}
|
||||
|
||||
do {
|
||||
lcg = lcg * 6364136223846793005 + 1442695040888963407
|
||||
carry = lcg.ushr(32).toInt()
|
||||
carry = rng.nextInt()
|
||||
} while(carry !in 0 until CMWC_CARRY_MAX)
|
||||
|
||||
stateIndex = state.size - 1
|
||||
|
@ -0,0 +1,86 @@
|
||||
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 java.lang.StringBuilder
|
||||
import java.util.random.RandomGenerator
|
||||
|
||||
// different from LegacyRandomSource minecraft uses in meaning that this class use different constants
|
||||
// and always use upper 32 bits instead of implementing BitRandomSource
|
||||
// AND it uses all bits from provided seed
|
||||
class LCG64Random(private var seed: Long = System.nanoTime()) : RandomGenerator, RandomSource {
|
||||
private val gaussian = MarsagliaPolarGaussian(this)
|
||||
|
||||
override fun setSeed(seed: Long) {
|
||||
this.seed = seed
|
||||
gaussian.reset()
|
||||
}
|
||||
|
||||
override fun nextInt(): Int {
|
||||
this.seed = MULTIPLIER * this.seed + INCREMENT
|
||||
return this.seed.ushr(32).toInt()
|
||||
}
|
||||
|
||||
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 LCG64Random(nextLong())
|
||||
}
|
||||
|
||||
override fun forkPositional(): PositionalRandomFactory {
|
||||
return Positional(nextLong())
|
||||
}
|
||||
|
||||
class Positional(val seed: Long) : PositionalRandomFactory {
|
||||
override fun at(x: Int, y: Int, z: Int): RandomSource {
|
||||
return LCG64Random(Mth.getSeed(x, y, z).xor(seed))
|
||||
}
|
||||
|
||||
override fun fromHashOf(name: String): RandomSource {
|
||||
return LCG64Random(name.hashCode().toLong().xor(seed))
|
||||
}
|
||||
|
||||
override fun fromSeed(seed: Long): RandomSource {
|
||||
return LCG64Random(seed)
|
||||
}
|
||||
|
||||
override fun parityConfigString(builder: StringBuilder) {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val MULTIPLIER = 6364136223846793005
|
||||
const val INCREMENT = 1442695040888963407
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user