Skip to content

Instantly share code, notes, and snippets.

@rossimo
Created November 20, 2016 15:04
Show Gist options
  • Save rossimo/8e6a2afaff5a85521e807ce292062177 to your computer and use it in GitHub Desktop.
Save rossimo/8e6a2afaff5a85521e807ce292062177 to your computer and use it in GitHub Desktop.
Event Loop
package demo
var console = System.out
data class State(val map: Array<Array<Int>>, val entities: List<Entity>)
fun State.update(enitity: Entity, transform: (Entity) -> Unit): State {
this.entities
.find { it == enitity }
?.apply { transform(this) }
return this
}
fun State.contains(location: Location): Boolean {
return location.x >= 0 && location.x < map[0].size
&& location.y >= 0 && location.y < map.size
}
fun State.accessible(location: Location): Boolean {
return this.map[location.y][location.x] == 1
}
data class Location(val x: Int, val y: Int)
data class Entity(var location: Location)
enum class Direction {
NORTH, SOUTH, WEST, EAST
}
interface Event {
fun run(state: State): State
}
class MoveEvent(val entity: Entity, val direction: Direction) : Event {
override fun run(state: State): State {
var x = entity.location.x
var y = entity.location.y
when (direction) {
Direction.NORTH -> y -= 1
Direction.SOUTH -> y += 1
Direction.WEST -> x -= 1
Direction.EAST -> x += 1
}
val location = Location(x, y)
return if (state.contains(location) && state.accessible(location))
state.update(entity) { it.location = location }
else
state
}
}
fun render(state: State) {
state.map.forEachIndexed { y, row ->
row.forEachIndexed { x, col ->
val entities = state.entities.filter { it.location.x == x && it.location.y == y }
val icon = if (entities.isNotEmpty()) {
"@"
} else if (state.map[y][x] == 1) {
"."
} else {
" "
}
console.print(icon)
}
console.print("\n")
}
}
fun main(args: Array<String>) {
val map = arrayOf(
arrayOf(1, 1, 1, 1, 0),
arrayOf(1, 1, 1, 1, 1),
arrayOf(0, 1, 1, 1, 1))
val player = Entity(Location(0, 0))
val entities = listOf(player)
var state = State(map, entities)
val events = listOf(
MoveEvent(player, Direction.SOUTH),
MoveEvent(player, Direction.SOUTH),
MoveEvent(player, Direction.EAST))
console.println("Initial:")
render(state)
console.println()
state = events.fold(state) { state, event ->
event.run(state)
}
console.println("Result:")
render(state)
console.println()
}
@rossimo
Copy link
Author

rossimo commented Nov 20, 2016

Initial:
@... 
.....
 ....

Result:
.... 
.@...
 ....

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment