Move PRNG implementation to Kommons
Yurie — Сегодня, в 15:09 вопрос почему все эти рандомы не в kommons
This commit is contained in:
parent
322d89f2a2
commit
430bc70c7e
@ -22,7 +22,7 @@ mixin_version=0.8.5
|
||||
neogradle.subsystems.parchment.minecraftVersion=1.21.1
|
||||
neogradle.subsystems.parchment.mappingsVersion=2024.11.17
|
||||
|
||||
kommons_version=3.1.3
|
||||
kommons_version=3.2.1
|
||||
caffeine_cache_version=3.1.5
|
||||
|
||||
jei_version=19.16.4.171
|
||||
|
@ -5,11 +5,11 @@ import net.minecraft.world.level.Level;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import ru.dbotthepony.mc.otm.core.IMatteryLevel;
|
||||
import ru.dbotthepony.mc.otm.core.util.Xoshiro256SSRandom;
|
||||
import ru.dbotthepony.mc.otm.core.util.Xoshiro256Random;
|
||||
|
||||
@Mixin(Level.class)
|
||||
public abstract class LevelMixin implements IMatteryLevel {
|
||||
public final RandomSource otm_random = new Xoshiro256SSRandom();
|
||||
public final RandomSource otm_random = new Xoshiro256Random();
|
||||
|
||||
@Override
|
||||
public @NotNull RandomSource getOtmRandom() {
|
||||
|
@ -5,6 +5,7 @@ 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 java.lang.StringBuilder
|
||||
import java.util.random.RandomGenerator
|
||||
|
||||
|
@ -0,0 +1,30 @@
|
||||
package ru.dbotthepony.mc.otm.core.util
|
||||
|
||||
import net.minecraft.util.RandomSource
|
||||
import java.util.random.RandomGenerator
|
||||
|
||||
interface IRandomSourceGenerator : RandomSource, RandomGenerator {
|
||||
override fun nextInt(): Int
|
||||
|
||||
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
|
||||
}
|
@ -6,8 +6,8 @@ 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
|
||||
import java.util.random.RandomGenerator
|
||||
|
||||
/**
|
||||
* Simple and insanely fast random number generator, which can be used for seeding (initializing internal state) of other number generators.
|
||||
@ -19,7 +19,7 @@ import java.util.random.RandomGenerator
|
||||
* * Always use upper 32 bits instead of implementing BitRandomSource and sampling some upper bits
|
||||
* * Uses all bits from provided seed
|
||||
*/
|
||||
class LCG64Random(private var seed: Long = RandomSupport.generateUniqueSeed()) : RandomGenerator, RandomSource {
|
||||
class LCG64RandomSource(seed: Long = RandomSupport.generateUniqueSeed()) : LCG64Random(seed), IRandomSourceGenerator {
|
||||
private val gaussian = MarsagliaPolarGaussian(this)
|
||||
|
||||
override fun setSeed(seed: Long) {
|
||||
@ -27,43 +27,12 @@ class LCG64Random(private var seed: Long = RandomSupport.generateUniqueSeed()) :
|
||||
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()
|
||||
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())
|
||||
return LCG64RandomSource(nextLong())
|
||||
}
|
||||
|
||||
override fun forkPositional(): PositionalRandomFactory {
|
||||
@ -72,15 +41,15 @@ class LCG64Random(private var seed: Long = RandomSupport.generateUniqueSeed()) :
|
||||
|
||||
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))
|
||||
return LCG64RandomSource(Mth.getSeed(x, y, z).xor(seed))
|
||||
}
|
||||
|
||||
override fun fromHashOf(name: String): RandomSource {
|
||||
return LCG64Random(name.hashCode().toLong().xor(seed))
|
||||
return LCG64RandomSource(name.hashCode().toLong().xor(seed))
|
||||
}
|
||||
|
||||
override fun fromSeed(seed: Long): RandomSource {
|
||||
return LCG64Random(seed)
|
||||
return LCG64RandomSource(seed)
|
||||
}
|
||||
|
||||
override fun parityConfigString(builder: StringBuilder) {
|
@ -0,0 +1,93 @@
|
||||
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(
|
||||
val s0: Long,
|
||||
val s1: Long,
|
||||
val s2: Long,
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
@ -1,138 +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 java.util.random.RandomGenerator
|
||||
|
||||
/**
|
||||
* Excellent number generator with guaranteed period of 2^255
|
||||
*/
|
||||
class Xoshiro256SSRandom private constructor(
|
||||
private var s0: Long,
|
||||
private var s1: Long,
|
||||
private var s2: Long,
|
||||
private var s3: Long,
|
||||
marker: Nothing?
|
||||
) : RandomGenerator, RandomSource {
|
||||
private val gaussian = MarsagliaPolarGaussian(this)
|
||||
|
||||
init {
|
||||
if (s0 or s1 or s2 or s3 == 0L) {
|
||||
s0 = 0x73CF3D83FFF44FF3L
|
||||
s1 = 0x6412312B70F3CD37L
|
||||
s2 = -0X6BB4C4E1327BFDCFL
|
||||
s3 = -0X4BE0F5BB5F3F5240L
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
||||
|
||||
constructor(seed: Long) : this(1L, 2L, 3L, 4L, null) {
|
||||
setSeed(seed)
|
||||
}
|
||||
|
||||
constructor() : this(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 nextLong(): Long {
|
||||
val result = (s1 * 5).rotateLeft(7) * 9
|
||||
val t = s1.shl(17)
|
||||
s2 = s2.xor(s0)
|
||||
s3 = s3.xor(s1)
|
||||
s1 = s1.xor(s2)
|
||||
s0 = s0.xor(s3)
|
||||
s2 = s2.xor(t)
|
||||
s3 = s3.rotateLeft(45)
|
||||
return result
|
||||
}
|
||||
|
||||
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 Xoshiro256SSRandom(nextLong(), nextLong(), nextLong(), nextLong(), null)
|
||||
}
|
||||
|
||||
override fun forkPositional(): PositionalRandomFactory {
|
||||
return Positional(nextLong(), nextLong(), nextLong(), nextLong())
|
||||
}
|
||||
|
||||
class Positional(
|
||||
val s0: Long,
|
||||
val s1: Long,
|
||||
val s2: Long,
|
||||
val s3: Long,
|
||||
) : PositionalRandomFactory {
|
||||
override fun at(x: Int, y: Int, z: Int): RandomSource {
|
||||
val rng = LCG64Random(Mth.getSeed(x, y, z))
|
||||
|
||||
return Xoshiro256SSRandom(
|
||||
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 Xoshiro256SSRandom(s0, HashCommon.murmurHash3(name.hashCode().toLong()).xor(s1), s2, s3)
|
||||
}
|
||||
|
||||
override fun fromSeed(seed: Long): RandomSource {
|
||||
return Xoshiro256SSRandom(seed)
|
||||
}
|
||||
|
||||
override fun parityConfigString(builder: StringBuilder) {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun raw(s0: Long, s1: Long, s2: Long, s3: Long): Xoshiro256SSRandom {
|
||||
return Xoshiro256SSRandom(s0, s1, s2, s3, null)
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user