Skip to content

Instantly share code, notes, and snippets.

@davepkennedy
Created October 14, 2015 10:40
Show Gist options
  • Save davepkennedy/4176ad36514f970cc9a7 to your computer and use it in GitHub Desktop.
Save davepkennedy/4176ad36514f970cc9a7 to your computer and use it in GitHub Desktop.
Invoke some block roughly some proportion of the time
def sumProbabilities[U] (options: Seq[(Int, () => U)]): Int = {
options.map {case (p, f) => p}.sum
}
def roughly [U] (chance: Int) (f: => U) = chance -> (() => f)
def chancesOf [U] (options: (Int, () => U)*): () => Option[U] = {
type Chance = PartialFunction[Int,Option[U]]
val fallback: Chance = {
case x => None
}
val sumProbs = sumProbabilities(options)
require (sumProbs <= 100, s"Sum of probabilities must not be more than 100% ($sumProbs)")
var max = 0
val chances: (Int) => Option[U] = options.map {
case (p, f) =>
println(s"$p => $f")
val min = max
max += p
(min to max) -> f
}.map {
case (range, func) =>
println (s"$range -> $func")
val pf: Chance = {
case x if range contains x => Some(func())
}
pf
}.foldRight (fallback) (_ orElse _)
val random = new Random()
def result () = chances(random.nextInt(100))
result
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment