I've created a Level for the 7 Day Roguelike Challenge that is supposed to implement the Iterable<T> interface so I can use all of those cool functions.
enum class FloorType {
Floor
Wall
}
class Level(val dimension: Dimension,
private val level: Array<FloorType>) {
val width = dimension.width
val height = dimension.height
val area = width * height
fun get(point: Point): FloorType {
return get(point.x, point.y)
}
fun get(x: Int, y: Int): FloorType {
return level[x + y * width]
}
}
fun Level.iterable(): Iterable<FloorType> {
return object: Iterable<FloorType> {
override fun iterator(): Iterator<FloorType> {
return iterator()
}
}
}
fun Level.iterator(): Iterator<FloorType> {
return object: Iterator<FloorType> {
var x = 0
var y = 0
override fun hasNext(): Boolean {
return (y != height)
}
override fun next(): FloorType {
val next = get(x, y)
x += 1
if (x % width == 0) {
y += 1
x = 0
}
return next
}
}
}
And the failing unit test
class CaveGeneratorSpec: Spek() {{
given("A cave generator with sensible configuration") {
val configurationUrl = javaClass<CaveGeneratorSpec>().getClassLoader()!!.getResource("settings.yml")!!
val configuration = loadConfiguration(configurationUrl.getPath()!!.substring(1))
val caveGenerator = CaveGenerator(configuration)
on("generating a 50x50 cave") {
val cave = caveGenerator.generate(Dimension(50, 50))
it(“should be partially filled with walls”) {
val numberOfWalls = cave.iterable().count { it == FloorType.Wall }
assertTrue(numberOfWalls != 0)
}
}
}
}}
With the exception:
java.lang.StackOverflowError
at com.sbg.arena.core.CorePackage$iterable$1.iterator(Level.kt:54)
at com.sbg.arena.core.CorePackage$iterable$1.iterator(Level.kt:54)
at com.sbg.arena.core.CorePackage$iterable$1.iterator(Level.kt:54)
at com.sbg.arena.core.CorePackage$iterable$1.iterator(Level.kt:54)
at com.sbg.arena.core.CorePackage$iterable$1.iterator(Level.kt:54)
at com.sbg.arena.core.CorePackage$iterable$1.iterator(Level.kt:54)
at com.sbg.arena.core.CorePackage$iterable$1.iterator(Level.kt:54)
at com.sbg.arena.core.CorePackage$iterable$1.iterator(Level.kt:54)
at com.sbg.arena.core.CorePackage$iterable$1.iterator(Level.kt:54)
...CaveGenerator uses a few dependencies which makes it unwieldy to show here. I propose you forgo creating the CaveGenerator and simply create a 2500-large Array:
on("generating a 50x50 cave") {
val random = Random()
val cave = Level(Dimension(50, 50), Array<FloorType>(2500, {
if (random.nextInt(100) > 50) FloorType.Wall else FloorType.Floor
}))
it(“should be partially filled with walls”) {
val numberOfWalls = cave.iterable().count { it == FloorType.Wall }
assertTrue(numberOfWalls != 0)
}
}
If you want to see the full source, the code is on my GitHub.