Implement Complementary Multiply-With-Curry Random
This commit is contained in:
parent
4e653b6544
commit
32ef2911fa
115
src/main/kotlin/ru/dbotthepony/mc/otm/core/util/CMWCRandom.kt
Normal file
115
src/main/kotlin/ru/dbotthepony/mc/otm/core/util/CMWCRandom.kt
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
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
|
||||||
|
|
||||||
|
class CMWCRandom(seed: Long = System.nanoTime(), private val stateSize: Int = CMWC_DEFAULT_STATE_SIZE) : RandomGenerator, RandomSource {
|
||||||
|
private val state = IntArray(stateSize)
|
||||||
|
private var carry = 0
|
||||||
|
private var stateIndex = 0
|
||||||
|
private val gaussian = MarsagliaPolarGaussian(this)
|
||||||
|
|
||||||
|
var seed: Long = seed
|
||||||
|
private set
|
||||||
|
|
||||||
|
init {
|
||||||
|
setSeed(seed)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setSeed(seed: Long) {
|
||||||
|
this.seed = seed
|
||||||
|
carry = Integer.remainderUnsigned(seed.toInt(), CMWC_CARRY_MAX)
|
||||||
|
|
||||||
|
// init state with regular LCG produced values
|
||||||
|
state[0] = seed.toInt()
|
||||||
|
state[1] = seed.shr(32).toInt()
|
||||||
|
|
||||||
|
for (i in 2 until state.size) {
|
||||||
|
state[i] = 69069 * state[i - 2] + 362437
|
||||||
|
}
|
||||||
|
|
||||||
|
stateIndex = state.size - 1
|
||||||
|
gaussian.reset()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun nextInt(): Int {
|
||||||
|
stateIndex = (stateIndex + 1) % state.size
|
||||||
|
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(), stateSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun forkPositional(): PositionalRandomFactory {
|
||||||
|
return Positional(nextLong(), stateSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
class Positional(val seed: Long, val stateSize: Int = CMWC_DEFAULT_STATE_SIZE) : PositionalRandomFactory {
|
||||||
|
override fun at(x: Int, y: Int, z: Int): RandomSource {
|
||||||
|
return CMWCRandom(Mth.getSeed(x, y, z).xor(seed), stateSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun fromHashOf(name: String): RandomSource {
|
||||||
|
return CMWCRandom(name.hashCode().toLong().xor(seed), stateSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun fromSeed(seed: Long): RandomSource {
|
||||||
|
return CMWCRandom(seed, stateSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun parityConfigString(builder: StringBuilder) {
|
||||||
|
throw UnsupportedOperationException()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val CMWC_DEFAULT_STATE_SIZE = 256 // 4096
|
||||||
|
const val CMWC_CARRY_MAX = 809430660
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user