Skip to content

Instantly share code, notes, and snippets.

@natec425
Created November 19, 2014 15:56
Show Gist options
  • Save natec425/36d7691d4c5b03b80cea to your computer and use it in GitHub Desktop.
Save natec425/36d7691d4c5b03b80cea to your computer and use it in GitHub Desktop.
Stream-based Conway
import util.Random
class Field(val height : Int, val width : Int, theDecider : (Int, Int) => Boolean) {
val grid = for ( i <- 0 until height )
yield (for ( j <- 0 until width ) yield theDecider(i,j))
def isInBounds(row : Int, col : Int) : Boolean =
(0 <= row && row < height) && (0 <= col && col < width)
def isOccupied(row : Int, col : Int) : Boolean =
isInBounds(row, col) && grid(row)(col)
def liveNeighbors(row : Int, col : Int) : Int =
((for (
d_row <- -1 to 1;
d_col <- -1 to 1
) yield if (isOccupied(row + d_row, col + d_col)) 1 else 0).sum) - ( if (isOccupied(row, col)) 1 else 0)
// I added the function argument for debugging purposes and just didn't bother to take it out
def print(f : (Int, Int) => String) =
for ( i <- 0 until height) {
for ( j <- 0 until width ) {
Console.print(f(i, j))
}
Console.println
}
def nextGeneration : Field = {
def lives(row : Int, col : Int) : Boolean =
(grid(row)(col), liveNeighbors(row, col)) match {
case (state, 2) => state
case (_, 3) => true
case _ => false
}
new Field(height, width, lives)
}
}
object NateConway extends App {
val life : Stream[Field] = {
def loop(current : Field): Stream[Field] = current #:: loop(current.nextGeneration)
loop(new Field(25, 25, (_,_) => Random.nextBoolean))
}
life.foreach{ field =>
field.print((i,j) => if (field.grid(i)(j)) "0" else ".")
println
Thread.sleep(200)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment