Skip to content

Instantly share code, notes, and snippets.

@matlux
Forked from mnd999/Ants.scala
Last active August 29, 2015 14:06
Show Gist options
  • Save matlux/255e2aea2b5a228cd07d to your computer and use it in GitHub Desktop.
Save matlux/255e2aea2b5a228cd07d to your computer and use it in GitHub Desktop.
package langtonsant
import scala.annotation.tailrec
import scala.collection.immutable.Map
object Ants extends App {
val columnNb = 50
val rowNb = 50
val grid = (0 until (rowNb * columnNb)).toList.map(_ => 0)
loop(State(grid, c2dtoc1d(25, 25), "n"))
def flip(grid: List[Int], index: Int): List[Int] = {
val state = grid(index)
grid.updated(index, if (state == 0) 1 else 0)
}
def step(oldState: State): State = {
render(oldState.grid)
// println(oldState)
val newDirection = if (oldState.grid(oldState.position) == 1) turnRight(oldState.direction)
else turnLeft(oldState.direction)
val newPosition = move(oldState.position, newDirection)
State(flip(oldState.grid, oldState.position), newPosition, newDirection)
}
@tailrec
def loop(state: State): State = {
loop(step(state))
}
def render(grid: List[Int]) {
println(grid.sliding(rowNb, columnNb).map(_.map(x => if (x == 0) "." else "#").mkString(" ")).mkString("\n"))
println
}
def c1dtoc2d(index: Int): Position = {
Position((index % columnNb), (index / columnNb))
}
def c2dtoc1d(x: Int, y: Int) = {
x + (y * columnNb)
}
def move(position: Int, direction: String): Int = {
val pos = c1dtoc2d(position)
direction match {
case "w" => c2dtoc1d((pos.x - 1) % rowNb, pos.y)
case "e" => c2dtoc1d((pos.x + 1) % rowNb, pos.y)
case "n" => c2dtoc1d(pos.x, (pos.y - 1) % columnNb)
case "s" => c2dtoc1d(pos.x, (pos.y + 1) % columnNb)
}
}
def turnLeft = Map("w" -> "s", "s" -> "e", "e" -> "n", "n" -> "w")
def turnRight = Map("w" -> "n", "s" -> "w", "e" -> "s", "n" -> "e")
case class State(grid: List[Int], position: Int, direction: String)
case class Position(x: Int, y: Int)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment