Skip to content

Instantly share code, notes, and snippets.

@ygrenzinger
Created November 15, 2019 09:26
Show Gist options
  • Save ygrenzinger/14c07301d2b97bea95abe48558d3c7d3 to your computer and use it in GitHub Desktop.
Save ygrenzinger/14c07301d2b97bea95abe48558d3c7d3 to your computer and use it in GitHub Desktop.
F-Bound Scala
package gameoflife
import scala.collection.immutable.Seq
case class FiniteGrid(override val size: Int, override val rows: Seq[Row]) extends Grid[FiniteGrid](size: Int, rows: Seq[Row]) {
override def changeCellAt(position: (Int, Int), state: CellState): FiniteGrid =
FiniteGrid(size, changeRowsAt(rows, position, state))
}
object FiniteGrid {
def create(size: Int, cellState: CellState): FiniteGrid =
FiniteGrid(size, (1 to size).map(_ => Row.create(size, cellState)))
}
package gameoflife
import scala.collection.immutable.Seq
abstract class Grid[A <: Grid[A]](val size: Int, val rows: Seq[Row]) {
def computeAliveNeighbours(position: (Int, Int)): Int = (for {
i <- Seq(-1, 0, 1).map(i => i + position._1)
j <- Seq(-1, 0, 1).map(j => j + position._2)
if (i, j) != position
} yield (i, j)).count(cellAt(_) == alive)
def cellAt(position: (Int, Int)): CellState =
rows.zipWithIndex
.find(_._2 == position._1)
.map(_._1.cellAt(position._2))
.getOrElse(dead)
protected def changeRowsAt(rows: Seq[Row], position: (Int, Int), state: CellState): Seq[Row] = {
rows.zipWithIndex
.map {
case (row, i) if (position._1 == i) => row.changeCellAt(position._2, state)
case (row, _) => row
}
}
def changeCellAt(position: (Int, Int), state: CellState): A
}
package gameoflife
import scala.collection.immutable.Seq
case class InfiniteGrid(override val size: Int, override val rows: Seq[Row]) extends Grid[InfiniteGrid](size: Int, rows: Seq[Row]) {
override def computeAliveNeighbours(position: (Int, Int)): Int =
super.computeAliveNeighbours(normalizePosition(position))
override def cellAt(position: (Int, Int)): CellState =
super.cellAt(normalizePosition(position))
override def changeCellAt(position: (Int, Int), state: CellState): InfiniteGrid =
InfiniteGrid(size, changeRowsAt(rows, position, state))
private def normalizePosition(position: (Int, Int)) =
(normalizeUnit(position._1), normalizeUnit(position._2))
private def normalizeUnit(x: Int) = {
val n = x % size
if (n >= 0) n else size - Math.abs(n)
}
}
object InfiniteGrid {
def create(size: Int, cellState: CellState): InfiniteGrid =
InfiniteGrid(size, (1 to size).map(_ => Row.create(size, cellState)))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment