Scala でライフゲームを書いてみた
2〜3時間で軽く書いてみました。
初めて Scala をガッツリ書いたのであまり Scala らしさが感じられないコードですが…。
[コード]
import scala.sys.process._ object Lifegame { type Table = List[List[Boolean]] val o = false val x = true def width(table: Table) = { table(0).size } def height(table: Table) = { table.size } def at_cell(table: Table, x: Int, y: Int) = { if(x < 0 || width(table) <= x) o else if(y < 0 || height(table) <= y) o else table(y)(x) } def dead_or_alive(table: Table, x: Int, y: Int) = { val cell = at_cell(table, x, y) val count = List( at_cell(table, x - 1, y - 1), at_cell(table, x - 0, y - 1), at_cell(table, x + 1, y - 1), at_cell(table, x + 1, y - 0), at_cell(table, x + 1, y + 1), at_cell(table, x - 0, y + 1), at_cell(table, x - 1, y + 1), at_cell(table, x - 1, y - 0) ).count(x => x) if(cell) count == 3 || count == 2 else count == 3 } def update(table: Table) = { table.zipWithIndex.map { case(row, y) => row.zipWithIndex.map { case(cell, x) => dead_or_alive(table, x, y) } } } def print(table: Table) = { Process("clear").run println(Range(0, width(table) + 2).map(x => "-").mkString) println(table.map(row => "|" + row.map(x => if(x) "*" else " " ).mkString).mkString("|\n") + "|") println(Range(0, width(table) + 2).map(x => "-").mkString) Console.flush() } def run(table: Table):Int = { print(table) Thread.sleep(500) run(update(table)) return 0 } def main(args: Array[String]) { val table = List( List(o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o), List(o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o), List(o, o, o, o, o, o, o, o, x, o, o, o, o, o, o, o, o, o, o, o, o, o, o), List(o, o, o, o, o, o, x, o, x, x, o, o, o, o, o, o, o, o, o, o, o, o, o), List(o, o, o, o, o, o, x, o, x, o, o, o, o, o, o, o, o, o, o, o, o, o, o), List(o, o, o, o, o, o, x, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o), List(o, o, o, o, x, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o), List(o, o, x, o, x, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o), List(o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o), List(o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o), List(o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o), List(o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o), List(o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o), List(o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o), List(o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o), List(o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o) ) run(table) } }
[所感]
要所要所でつまずいたものの、全体的にみればそこまで難しくなかったかなーという感じです。
まあ元々 C++ の実装をそのまま Scala で書きなおしただけですしね(なので Scala らしさがあまりないとも言える
型に関しては C++ よりも厳しいという印象を受けました。
本当は List[List[Boolean]]
という型に依存したくなかったんですが、上手く消すことが出来なかった…。
ダックタイピングするだけでも結構いろいろと記述必要があるぽいのがちょっと厳しい…(良し悪しは別として。
Scala は他にはパターンマッチや trait、Structural Subtyping、implicit あたりなど面白い機能があるぽいので、次 Scala を書くときはそのあたりを少し意識してかいてみたい。