Skip to content

Instantly share code, notes, and snippets.

@bripkens
Last active November 15, 2015 16:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bripkens/bf2b0408dba6efebf528 to your computer and use it in GitHub Desktop.
Save bripkens/bf2b0408dba6efebf528 to your computer and use it in GitHub Desktop.
Game of Life in Scala
package de.bripkens
object GameOfLife {
case class Point(x: Int, y: Int) {
lazy val neighbours: Seq[Point] = for (
xDistance <- -1 to 1;
yDistance <- -1 to 1;
eachPoint = Point(x + xDistance, y + yDistance);
if !(eachPoint.x == x && eachPoint.y == y)
) yield eachPoint
def getNumberOfLivingNeighbours(field: Field): Int = {
(neighbours.toSet -- (neighbours.toSet -- field)).size
}
}
type Field = Set[Point]
def createField(points: Point*): Field = {
points.toSet
}
def tick(field: Field): Field = {
val survivors = field.groupBy(identity(_))
.mapValues(_.head.getNumberOfLivingNeighbours(field))
.filter(2 to 3 contains _._2)
.keySet
val newborns = field.toList
.flatMap(_.neighbours)
.groupBy(identity(_))
.--(field)
.mapValues(_.size)
.filter(_._2 == 3)
.keySet
survivors ++ newborns
}
}
package de.bripkens
import com.bripkens.GameOfLife
import com.bripkens.GameOfLife.{Point}
import org.scalatest.{FlatSpec, Matchers}
class GameOfLifeSpec extends FlatSpec with Matchers {
"tick" should "remove living cells when areas are underpopulated with no neighbours" in {
val field = GameOfLife.createField(Point(1, 1))
GameOfLife.tick(field) should not contain Point(1, 1)
}
it should "remove living cells when areas are underpopulated with one neighbour" in {
val field = GameOfLife.createField(Point(1, 1), Point(0, 0))
GameOfLife.tick(field) should not contain Point(1, 1)
}
it should "retain cells with two neighbours" in {
val field = GameOfLife.createField(Point(1, 1), Point(0, 0), Point(0, 1))
GameOfLife.tick(field) should contain (Point(1, 1))
}
it should "retain cells with three neighbours" in {
val field = GameOfLife.createField(Point(1, 1), Point(0, 0), Point(0, 1), Point(1, 0))
GameOfLife.tick(field) should contain (Point(1, 1))
}
it should "handle reproduction of cells with exactly three neighbours" in {
val field = GameOfLife.createField(Point(0, 0), Point(0, 1), Point(0, 2))
GameOfLife.tick(field) should contain (Point(1, 1))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment