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.minecraftVersion=1.21.1
|
||||||
neogradle.subsystems.parchment.mappingsVersion=2024.11.17
|
neogradle.subsystems.parchment.mappingsVersion=2024.11.17
|
||||||
|
|
||||||
kommons_version=3.1.3
|
kommons_version=3.2.1
|
||||||
caffeine_cache_version=3.1.5
|
caffeine_cache_version=3.1.5
|
||||||
|
|
||||||
jei_version=19.16.4.171
|
jei_version=19.16.4.171
|
||||||
|
@ -5,11 +5,11 @@ import net.minecraft.world.level.Level;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import ru.dbotthepony.mc.otm.core.IMatteryLevel;
|
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)
|
@Mixin(Level.class)
|
||||||
public abstract class LevelMixin implements IMatteryLevel {
|
public abstract class LevelMixin implements IMatteryLevel {
|
||||||
public final RandomSource otm_random = new Xoshiro256SSRandom();
|
public final RandomSource otm_random = new Xoshiro256Random();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NotNull RandomSource getOtmRandom() {
|
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.MarsagliaPolarGaussian
|
||||||
import net.minecraft.world.level.levelgen.PositionalRandomFactory
|
import net.minecraft.world.level.levelgen.PositionalRandomFactory
|
||||||
import net.minecraft.world.level.levelgen.RandomSupport
|
import net.minecraft.world.level.levelgen.RandomSupport
|
||||||
|
import ru.dbotthepony.kommons.random.LCG64Random
|
||||||
import java.lang.StringBuilder
|
import java.lang.StringBuilder
|
||||||
import java.util.random.RandomGenerator
|
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.MarsagliaPolarGaussian
|
||||||
import net.minecraft.world.level.levelgen.PositionalRandomFactory
|
import net.minecraft.world.level.levelgen.PositionalRandomFactory
|
||||||
import net.minecraft.world.level.levelgen.RandomSupport
|
import net.minecraft.world.level.levelgen.RandomSupport
|
||||||
|
import ru.dbotthepony.kommons.random.LCG64Random
|
||||||
import java.lang.StringBuilder
|
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.
|
* 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
|
* * Always use upper 32 bits instead of implementing BitRandomSource and sampling some upper bits
|
||||||
* * Uses all bits from provided seed
|
* * 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)
|
private val gaussian = MarsagliaPolarGaussian(this)
|
||||||
|
|
||||||
override fun setSeed(seed: Long) {
|
override fun setSeed(seed: Long) {
|
||||||
@ -27,43 +27,12 @@ class LCG64Random(private var seed: Long = RandomSupport.generateUniqueSeed()) :
|
|||||||
gaussian.reset()
|
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 {
|
override fun nextGaussian(): Double {
|
||||||
return gaussian.nextGaussian()
|
return gaussian.nextGaussian()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun fork(): RandomSource {
|
override fun fork(): RandomSource {
|
||||||
return LCG64Random(nextLong())
|
return LCG64RandomSource(nextLong())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun forkPositional(): PositionalRandomFactory {
|
override fun forkPositional(): PositionalRandomFactory {
|
||||||
@ -72,15 +41,15 @@ class LCG64Random(private var seed: Long = RandomSupport.generateUniqueSeed()) :
|
|||||||
|
|
||||||
class Positional(val seed: Long) : PositionalRandomFactory {
|
class Positional(val seed: Long) : PositionalRandomFactory {
|
||||||
override fun at(x: Int, y: Int, z: Int): RandomSource {
|
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 {
|
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 {
|
override fun fromSeed(seed: Long): RandomSource {
|
||||||
return LCG64Random(seed)
|
return LCG64RandomSource(seed)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun parityConfigString(builder: StringBuilder) {
|
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