Skip to content

Instantly share code, notes, and snippets.

@kaja47
Created September 18, 2012 05:04
Show Gist options
  • Select an option

  • Save kaja47/3741364 to your computer and use it in GitHub Desktop.

Select an option

Save kaja47/3741364 to your computer and use it in GitHub Desktop.
Conway's game of life
import collection.immutable.BitSet
case class Matrix(w: Int, h: Int, bitmap: BitSet) {
def reset(cells: Seq[(Int, Int)]): Matrix =
copy(bitmap = BitSet() ++ (cells map (pos _).tupled))
def pos(x: Int, y: Int): Int = x + y * w
def at(x: Int, y: Int): Boolean = bitmap(pos(x, y))
def liveNeighbours(x: Int, y: Int): Int =
(for {
δx <- -1 to 1
δy <- -1 to 1
if !(δx == 0 && δy == 0) // exclude self
if at(x + δx, y + δy)
} yield 1).size
def cellSurvive(x: Int, y: Int): Boolean =
(at(x, y), liveNeighbours(x, y)) match {
case (true, 2) => true
case (true, 3) => true
case (false, 3) => true
case _ => false
}
def nextStep: Matrix =
reset(for {
x <- 0 until w
y <- 0 until h
if cellSurvive(x, y)
} yield (x, y))
def rows = 0 until (w * h) map bitmap grouped w
}
def draw(m: Matrix) =
for (row <- m.rows) {
//println(row map { if (_) "X" else " " } mkString)
for (e <- row) print(if (e) "X" else " ")
println("|")
}
def matrixFromPoints(w: Int, h: Int)(cells: (Int, Int)*) = Matrix(w, h, BitSet()).reset(cells)
def matrixFromSchema(schema: Seq[String]) = {
val w = schema map (_.size) min
val h = schema.size
val points = for {
x <- 0 until w
y <- 0 until h
if schema(y)(x) == 'X'
} yield (x, y)
matrixFromPoints(w, h)(points: _*)
}
def padding(schema: Seq[String], padding: Int) = {
val w = schema map (_.size) min
def line(len: Int) = "." * len
def linePadding = Seq.fill(padding)(line(w + 2 * padding))
linePadding ++ (schema map { l => line(padding) + l + line(padding) }) ++ linePadding
}
val schema = Seq(
"................",
"................",
"................",
".....X...XXX....",
".....XXX..X.....",
"......X.........",
"................",
"................"
)
var g = matrixFromSchema(padding(schema, 30))
for(gen <- 0 to 1000) {
g = g.nextStep
draw(g)
println()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment