In my game dungeon generator made in Scala, I have a recursive function that generates a "tree-like" structure. It takes in a pure random number generator (RNG), and outputs a random tree and a new random number generator.
My issue is that because it's recursive, and every time my function branches out, I don't want to pass in the same RNG to both branches, so I have to keep an inner var
inside my outer function.
An excerpt from my code:
def generate(parameters: RandomBSPTreeParameters)(rng: RNG): (BSPTree, RNG) = {
var varRng: RNG = rng
def inner(size: Size, verticalSplit: Boolean): BSPTree = {
def verticalBranch = {
val leeway = size.height - parameters.minLeafEdgeLength.value * 2
val (topHeightOffset, newRng) = RNG.nextPositiveInt(leeway)(varRng)
varRng = newRng
val topHeight = parameters.minLeafEdgeLength.value + topHeightOffset
VerticalBranch(
inner(Size(size.width, topHeight), verticalSplit = false),
inner(Size(size.width, size.height - topHeight), verticalSplit = false)
)
}
def horizontalBranch = {
val leeway = size.width - parameters.minLeafEdgeLength.value * 2
val (topWidthOffset, newRng) = RNG.nextPositiveInt(leeway)(varRng)
varRng = newRng
val leftWidth = parameters.minLeafEdgeLength.value + topWidthOffset
HorizontalBranch(
inner(Size(leftWidth, size.height), verticalSplit = true),
inner(Size(size.width - leftWidth, size.height), verticalSplit = true)
)
}
def randomOrientationBranch = {
val (splitVertically, newRng) = RNG.nextBoolean(varRng)
varRng = newRng
if (splitVertically)
verticalBranch
else
horizontalBranch
}
if(size.surface > parameters.minLeafSurface)
size.shape match {
case Square if size.width > parameters.minLeafEdgeLength.value * 2 => randomOrientationBranch
case SkewedHorizontally if size.width > parameters.minLeafEdgeLength.value * 2 => horizontalBranch
case SkewedVertically if size.height > parameters.minLeafEdgeLength.value * 2 => verticalBranch
}
else Leaf(size)
}
val (firstSplitIsVertical, newRng) = RNG.nextBoolean(varRng)
varRng = newRng
val tree = inner(parameters.size, firstSplitIsVertical)
(tree, varRng)
}
Can somebody guide me in the right direction for eliminating the need to keep the var varRng: RNG
in this function, and make it state-less.