Skip to content

Instantly share code, notes, and snippets.

@fsarradin
Created November 13, 2015 21:57
Show Gist options
  • Save fsarradin/84675258c79d2bf10fb8 to your computer and use it in GitHub Desktop.
Save fsarradin/84675258c79d2bf10fb8 to your computer and use it in GitHub Desktop.
Part of Conway's game of life in Scala
package me.conway
object cell {
class Cells(end: Location, cells: Set[Location] = Set.empty) {
val neighbourhood = Seq(
Location(-1, -1), Location(0, -1), Location(1, -1),
Location(-1, 0), Location(1, 0),
Location(-1, 1), Location(0, 1), Location(1, 1)
)
def countLivingAround(location: Location): Int =
neighbourhood
.map(ofs => if (isLiving(ofs + location)) 1 else 0)
.sum
def isLiving(location: Location) =
cells.contains(location)
def withLivingCellAt(location: Location): Cells =
new Cells(end, cells + location)
def withLivingCellsAt(locations: Location*): Cells =
locations.foldLeft(this)(_ withLivingCellAt _)
}
case class Location(x: Int, y: Int) {
def +(other: Location): Location =
Location(x + other.x, y + other.y)
}
object GolRuleEngine {
def willBeLiving(location: Location, cells: Cells): Boolean = {
val count = cells.countLivingAround(location)
count >= 2 && count <= 3
}
}
}
package me.conway
import me.conway.cell.{Cells, Location}
import org.scalatest.{Matchers, FunSuiteLike}
import scala.language.implicitConversions
class CellsTest extends FunSuiteLike with Matchers {
implicit def tuple2Location(t: (Int, Int)): Location = Location(t._1, t._2)
test("should indicates dead where a cell is dead") {
val cells = new Cells((10, 10))
cells.isLiving((1, 1)) should be (false)
}
test("should indicates living where a cell is living") {
val cells =
new Cells((10, 10)).withLivingCellAt((1, 1))
cells.isLiving((1, 1)) should be (true)
}
test("should count no living cell where there is no living cells") {
val cells = new Cells((10, 10))
cells.countLivingAround((1, 1)) should be (0)
}
test("should count 8 living cells around a cell where all neighbourhood is living") {
val cells =
new Cells((10, 10)).withLivingCellsAt(
(0, 0), (1, 0), (2, 0),
(0, 1), (2, 1),
(0, 2), (1, 2), (2, 2)
)
cells.countLivingAround(Location(1, 1)) should be (8)
}
}
package me.conway
import me.conway.cell.{GolRuleEngine, Cells, Location}
import org.scalatest.{Matchers, FunSuiteLike}
class GolRuleEngineTest extends FunSuiteLike with Matchers {
implicit def tuple2Location(t: (Int, Int)): Location = Location(t._1, t._2)
test("should be dead when dead cell with no living cells around") {
val cells = new Cells((10, 10))
GolRuleEngine.willBeLiving((1, 1), cells) should be (false)
}
test("should be dead when living cell with no living cells around") {
val cells = new Cells((10, 10)).withLivingCellAt((1, 1))
GolRuleEngine.willBeLiving((1, 1), cells) should be (false)
}
test("should live when living cell with 2 living cells around") {
val cells = new Cells((10, 10))
.withLivingCellsAt((0, 1), (1, 1), (2, 1))
GolRuleEngine.willBeLiving((1, 1), cells) should be (true)
}
test("should live when living cell with 3 living cells around") {
val cells = new Cells((10, 10))
.withLivingCellsAt((1, 0), (0, 1), (1, 1), (2, 1))
GolRuleEngine.willBeLiving((1, 1), cells) should be (true)
}
test("should died when living cell with 4 living cells around") {
val cells = new Cells((10, 10))
.withLivingCellsAt((1, 0), (0, 1), (1, 1), (2, 1), (1, 2))
GolRuleEngine.willBeLiving((1, 1), cells) should be (false)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment