
walkmc.WeightedDice.kt Maven / Gradle / Ivy
package walkmc
import walkmc.collections.*
import walkmc.extensions.numbers.*
/**
* Assigns a probabilty to each distinct [T] item, and randomly selects [T] values given those probabilities.
*
* In other words, this is a Probability Density Function (PDF) for discrete [T] values
*/
open class WeightedDice(probabilities: Map) {
constructor(vararg values: Pair) : this(values.toMap())
/**
* The sum of all probabilities.
*/
private val sum = probabilities.values.sum()
/**
* The distribution of the probabilities.
*/
val distribution = with(probabilities) {
var binStart = 0.0
asSequence()
.sortedBy { it.value }
.map { it.key to OpenDoubleRange(binStart, it.value + binStart) }
.onEach { binStart = it.second.endExclusive }
.toMap()
}
/**
* Randomly selects a [T] value with probability
*/
fun roll() = with(randomDouble(0.0..sum)) {
distribution
.asIterable()
.first { this in it.value }
.key
}
}
/**
* Creates a new empty [WeightedDice].
*/
fun weightedDiceOf() = WeightedDice()
/**
* Creates a new [WeightedDice] with the given [elements].
*/
fun weightedDiceOf(vararg elements: Pair) = WeightedDice(*elements)
/**
* Creates a new [WeightedDice] by this map.
*/
fun Map.toWeightedDice() = WeightedDice(this)
© 2015 - 2025 Weber Informatics LLC | Privacy Policy