生きているセルだけを考えていればLifeGameは作れる。そうなるとListとタプルがあれば、2次元配列はいらない事に気づいたのでやってみた。
class Life(var l: List[(Int, Int)]) { def next() { l = step(l); } def step(l: List[(Int, Int)]): List[(Int, Int)] = { val m = countLife(l.flatMap(LifeAround).sort(tSort)).sort(mSort); nextLife(m, l).sort(tSort); } def countLife(l: List[(Int, Int)]): List[((Int, Int), Int)] = { def c(h: (Int, Int), i: Int, l: List[(Int, Int)]): List[((Int, Int), Int)] = { l match { case x :: xs => if (h == x) c(x, i + 1, xs) else (h, i) :: c(x, 1, xs); case _ => List((h, i)); } } l match { case x :: xs => c(x, 1, xs); case _ => List[((Int, Int), Int)](); } } def LifeAround(t: (Int, Int)): List[(Int, Int)] = { val x = t._1; val y = t._2; List((x - 1, y - 1), (x - 1, y), (x - 1, y + 1), (x, y - 1), (x, y), (x, y + 1), (x + 1, y - 1), (x + 1, y), (x + 1, y + 1)) } def tSort(s: (Int, Int), n: (Int, Int)): Boolean = { if (s._1 < n._1) true else if (s._1 == n._1) if (s._2 < n._2) true else if (s._2 == n._2) true else false else false } def mSort(s: ((Int, Int), Int), n: ((Int, Int), Int)): Boolean = { tSort(s._1, n._1); } def nextLife(m: List[((Int, Int), Int)], l: List[(Int, Int)]): List[(Int, Int)] = { if (m.isEmpty) List() else if (l.isEmpty == false && m.head._1 == l.head) { if (m.head._2 == 3 || m.head._2 == 4) { l.head :: nextLife(m.tail, l.tail); } else { nextLife(m.tail, l.tail); } } else { if (m.head._2 == 3) m.head._1 :: nextLife(m.tail, l) else nextLife(m.tail, l); } } override def toString() = { l = l.sort(tSort); val xMin = l.foldLeft(1)((z, x) => if (z < x._1) z else x._1) - 1; val yMin = l.foldLeft(1)((z, x) => if (z < x._2) z else x._2) - 1; val xMax = l.foldLeft(1)((z, x) => if (z < x._1) x._1 else z) + 1; val yMax = l.foldLeft(1)((z, x) => if (z < x._2) x._2 else z) + 1; def f(p: (Int, Int), l: List[(Int, Int)]): String = { l match { case x :: xs => (if (p._1 < x._1) { " . " * (yMax - p._2) + "\n" + ((" . " * (yMax-yMin+1)) + "\n") * (x._1 - p._1 - 1) + " . " * (x._2 - yMin) } else " . " * (x._2 - p._2 - 1)) + " * " + f(x, xs); case _ => " . " * (yMax - p._2) + "\n . " + ((" . " * (yMax - yMin)) + "\n") } } l match { case x :: xs => " . " + f((xMin, yMin), l); case _ => " . "; } } } object Lifegame { def main() { var l = List((1, 2), (2, 3), (3, 1), (3, 2), (3, 3)); val lifegame = new Life(l); println(lifegame); for (i <- 1 to 10) { lifegame.next(); println(lifegame); } } }
改めて見るとコードが汚い