Move random extensions to RandomUtils file

This commit is contained in:
DBotThePony 2025-03-26 19:34:22 +07:00
parent e93c766edb
commit 5663b262eb
Signed by: DBot
GPG Key ID: DCC23B5715498507
2 changed files with 103 additions and 97 deletions

View File

@ -10,7 +10,6 @@ import com.google.common.collect.ImmutableSet
import com.google.gson.JsonElement
import com.google.gson.JsonObject
import com.google.gson.JsonPrimitive
import it.unimi.dsi.fastutil.ints.IntList
import it.unimi.dsi.fastutil.objects.ObjectComparators
import net.minecraft.Util
import net.minecraft.core.BlockPos
@ -29,7 +28,6 @@ import net.minecraft.network.chat.contents.TranslatableContents
import net.minecraft.resources.ResourceKey
import net.minecraft.resources.ResourceLocation
import net.minecraft.tags.TagKey
import net.minecraft.util.RandomSource
import net.minecraft.world.entity.Entity
import net.minecraft.world.item.Item
import net.minecraft.world.item.ItemStack
@ -65,13 +63,10 @@ import java.util.concurrent.Callable
import java.util.concurrent.Future
import java.util.function.Consumer
import java.util.function.Supplier
import java.util.random.RandomGenerator
import java.util.stream.Stream
import java.util.stream.StreamSupport
import kotlin.NoSuchElementException
import kotlin.jvm.optionals.getOrNull
import kotlin.math.ln
import kotlin.math.sqrt
import kotlin.reflect.KProperty
operator fun RecipeInput.get(index: Int): ItemStack = getItem(index)
@ -189,43 +184,6 @@ fun <T : Enum<T>> T.prev(values: Array<out T>): T {
return values[next]
}
fun IntArray.shuffle(random: RandomSource): IntArray {
for (i in lastIndex downTo 1) {
val j = random.nextInt(i + 1)
val copy = this[i]
this[i] = this[j]
this[j] = copy
}
return this
}
fun <L : IntList> L.shuffle(random: RandomSource): L {
for (i in lastIndex downTo 1) {
val j = random.nextInt(i + 1)
set(j, set(i, getInt(j)))
}
return this
}
fun <T, L : MutableList<T>> L.shuffle(random: RandomSource): L {
Util.shuffle(this, random)
return this
}
fun <T> List<T>.random(random: RandomGenerator): T {
if (isEmpty())
throw NoSuchElementException("This list is empty")
return get(random.nextInt(size))
}
fun <T> List<T>.random(random: RandomSource): T {
if (isEmpty())
throw NoSuchElementException("This list is empty")
return get(random.nextInt(size))
}
inline fun <T : Any> immutableList(size: Int, initializer: (index: Int) -> T): ImmutableList<T> {
require(size >= 0) { "Invalid list size $size" }
@ -635,58 +593,3 @@ infix fun FluidStack.isNotSameAs(other: FluidStack): Boolean {
return !FluidStack.isSameFluidSameComponents(this, other) && amount == other.amount
}
data class DoublePair(val first: Double, val second: Double)
fun RandomSource.nextUUID(): UUID {
return UUID(nextLong(), nextLong())
}
// normal distribution via Marsaglia polar method
fun RandomGenerator.nextNormalDoubles(stddev: Double, mean: Double): DoublePair {
var rand1: Double
var rand2: Double
var distSqr: Double
do {
rand1 = 2.0 * nextDouble() - 1.0
rand2 = 2.0 * nextDouble() - 1.0
distSqr = rand1 * rand1 + rand2 * rand2
} while (distSqr >= 1.0 || distSqr == 0.0)
val mapping = sqrt(-2.0 * ln(distSqr) / distSqr)
return DoublePair(
rand1 * mapping * stddev + mean,
rand2 * mapping * stddev + mean
)
}
// All Mojang's random sources use MarsagliaPolarGaussian for generating normal distributed doubles
fun RandomSource.nextNormalDoubles(stddev: Double, mean: Double): DoublePair {
return DoublePair(
nextGaussian() * stddev + mean,
nextGaussian() * stddev + mean
)
}
fun RandomSource.nextNormalDouble(stddev: Double, mean: Double): Double {
return nextGaussian() * stddev + mean
}
fun RandomSource.nextFloat(min: Float, max: Float): Float {
if (this is RandomGenerator)
return nextFloat(min, max)
require(max >= min) { "Min is bigger than max: $min vs $max" }
if (min == max) return min
return min + nextFloat() * (max - min)
}
fun RandomSource.nextDouble(min: Double, max: Double): Double {
if (this is RandomGenerator)
return nextDouble(min, max)
require(max >= min) { "Min is bigger than max: $min vs $max" }
if (min == max) return min
return min + nextDouble() * (max - min)
}

View File

@ -0,0 +1,103 @@
package ru.dbotthepony.mc.otm.core
import it.unimi.dsi.fastutil.ints.IntList
import net.minecraft.Util
import net.minecraft.util.RandomSource
import java.util.*
import java.util.random.RandomGenerator
import kotlin.NoSuchElementException
import kotlin.math.ln
import kotlin.math.sqrt
data class DoublePair(val first: Double, val second: Double)
fun RandomSource.nextUUID(): UUID {
return UUID(nextLong(), nextLong())
}
// normal distribution via Marsaglia polar method
fun RandomGenerator.nextNormalDoubles(stddev: Double, mean: Double): DoublePair {
var rand1: Double
var rand2: Double
var distSqr: Double
do {
rand1 = 2.0 * nextDouble() - 1.0
rand2 = 2.0 * nextDouble() - 1.0
distSqr = rand1 * rand1 + rand2 * rand2
} while (distSqr >= 1.0 || distSqr == 0.0)
val mapping = sqrt(-2.0 * ln(distSqr) / distSqr)
return DoublePair(
rand1 * mapping * stddev + mean,
rand2 * mapping * stddev + mean
)
}
// All Mojang's random sources use MarsagliaPolarGaussian for generating normal distributed doubles
fun RandomSource.nextNormalDoubles(stddev: Double, mean: Double): DoublePair {
return DoublePair(
nextGaussian() * stddev + mean,
nextGaussian() * stddev + mean
)
}
fun RandomSource.nextNormalDouble(stddev: Double, mean: Double): Double {
return nextGaussian() * stddev + mean
}
fun RandomSource.nextFloat(min: Float, max: Float): Float {
if (this is RandomGenerator)
return nextFloat(min, max)
require(max >= min) { "Min is bigger than max: $min vs $max" }
if (min == max) return min
return min + nextFloat() * (max - min)
}
fun RandomSource.nextDouble(min: Double, max: Double): Double {
if (this is RandomGenerator)
return nextDouble(min, max)
require(max >= min) { "Min is bigger than max: $min vs $max" }
if (min == max) return min
return min + nextDouble() * (max - min)
}
fun IntArray.shuffle(random: RandomSource): IntArray {
for (i in lastIndex downTo 1) {
val j = random.nextInt(i + 1)
val copy = this[i]
this[i] = this[j]
this[j] = copy
}
return this
}
fun <L : IntList> L.shuffle(random: RandomSource): L {
for (i in lastIndex downTo 1) {
val j = random.nextInt(i + 1)
set(j, set(i, getInt(j)))
}
return this
}
fun <T, L : MutableList<T>> L.shuffle(random: RandomSource): L {
Util.shuffle(this, random)
return this
}
fun <T> List<T>.random(random: RandomGenerator): T {
if (isEmpty())
throw NoSuchElementException("This list is empty")
return get(random.nextInt(size))
}
fun <T> List<T>.random(random: RandomSource): T {
if (isEmpty())
throw NoSuchElementException("This list is empty")
return get(random.nextInt(size))
}