Skip to content

Instantly share code, notes, and snippets.

@omiend
Last active August 29, 2015 14:11
Show Gist options
  • Save omiend/8e4e16583db99f0a8223 to your computer and use it in GitHub Desktop.
Save omiend/8e4e16583db99f0a8223 to your computer and use it in GitHub Desktop.
Life Game
import scala.annotation.tailrec
object LifeGame {
def main(args: Array[String]) = {
queenBee
}
/**
* ライフゲーム
*/
@tailrec
def execute(nowGeneration: List[List[Int]]) {
// 現世代を次世代にコピー
var nextGeneration: List[List[Int]] = nowGeneration
drow(nowGeneration)
for (rowIndex <- nowGeneration.zipWithIndex) {
for (cellIndex <- nowGeneration(rowIndex._2).zipWithIndex) {
val i: Int = roule(rowIndex._2, cellIndex._2, nowGeneration)
nextGeneration = nextGeneration.updated(rowIndex._2, nextGeneration(rowIndex._2).updated(cellIndex._2, i))
}
}
Thread.sleep(250);
// 次世代の処理へ
execute(nextGeneration)
}
/**
* ライフゲーム ルール
*/
def roule(x: Int, y: Int, target: List[List[Int]]): Int = {
// ■座標の場合、◆座標から◇座標までを取得してyieldで返却し、その和をもって次世代での状態(0→死,1→生)を返却する
// 現在対象となっている座標のセルは処理しない 「if !(x == xx && y == yy))」
// ◆□□
// □■□
// □□◇
(for (xx <- List.range(x - 1, x + 2); yy <- List.range(y - 1, y + 2) if !(x == xx && y == yy)) yield {
try {
target(xx)(yy)
} catch {
case e: IndexOutOfBoundsException => 0 // 何もしない
}
}).sum match {
case i if i >= 4 || i <= 1 => 0 // 死
case i if i == 3 => 1 // 誕生
case _ => target(x)(y) // 変異なし
}
}
/**
* コンソール出力
*/
def drow(generation: List[List[Int]]) {
println("")
generation map { cellList =>
cellList map {
case 1 => print("■")
case _ => print("□")
}
println("")
}
}
// *
// * 以下、テンプレート
// *
// ブリンカー
def blinker = LifeGame.execute(List(
List(0,0,0)
,List(1,1,1)
,List(0,0,0)
))
// ヒキガエル
def glosbe = LifeGame.execute(List(
List(0,1,1,0)
,List(1,0,0,0)
,List(0,0,0,1)
,List(0,1,1,0)
))
// ビーコン
def becon = LifeGame.execute(List(
List(1,1,0,0)
,List(1,0,0,0)
,List(0,0,0,1)
,List(0,0,1,1)
))
// 時計
def clock = LifeGame.execute(List(
List(0,1,0,0)
,List(0,1,0,1)
,List(1,0,1,0)
,List(0,0,1,0)
))
// 八角形
def octagon = LifeGame.execute(List(
List(0,0,0,1,1,0,0,0)
,List(0,0,1,0,0,1,0,0)
,List(0,1,0,0,0,0,1,0)
,List(1,0,0,0,0,0,0,1)
,List(1,0,0,0,0,0,0,1)
,List(0,1,0,0,0,0,1,0)
,List(0,0,1,0,0,1,0,0)
,List(0,0,0,1,1,0,0,0)
))
// パルサー
def pulser = LifeGame.execute(List(
List(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
,List(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
,List(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
,List(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
,List(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
,List(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
,List(0,0,0,0,0,1,0,0,0,1,0,0,0,0,0)
,List(0,0,0,0,0,1,0,1,0,1,0,0,0,0,0)
,List(0,0,0,0,0,1,0,0,0,1,0,0,0,0,0)
,List(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
,List(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
,List(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
,List(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
,List(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
,List(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
))
// 銀河
def galaxy = LifeGame.execute(List(
List(0,0,0,0,0,0,0,0,0,0,0,0,0)
,List(0,0,0,0,0,0,0,0,0,0,0,0,0)
,List(0,0,1,1,1,1,1,1,0,1,1,0,0)
,List(0,0,1,1,1,1,1,1,0,1,1,0,0)
,List(0,0,0,0,0,0,0,0,0,1,1,0,0)
,List(0,0,1,1,0,0,0,0,0,1,1,0,0)
,List(0,0,1,1,0,0,0,0,0,1,1,0,0)
,List(0,0,1,1,0,0,0,0,0,1,1,0,0)
,List(0,0,1,1,0,0,0,0,0,0,0,0,0)
,List(0,0,1,1,0,1,1,1,1,1,1,0,0)
,List(0,0,1,1,0,1,1,1,1,1,1,0,0)
,List(0,0,0,0,0,0,0,0,0,0,0,0,0)
,List(0,0,0,0,0,0,0,0,0,0,0,0,0)
))
// 女王蜂
def queenBee = LifeGame.execute(List(
List(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
,List(0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0)
,List(0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0)
,List(0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1,0,0,0,0)
,List(1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,0,0,1,1)
,List(1,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1,0,0,1,1)
,List(0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0)
,List(0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0)
,List(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
))
// ----------------------------------
// Map版
// ----------------------------------
@tailrec
def execute2(nowGeneration: Map[Int, Map[Int, Int]]) {
// 現世代を次世代にコピー
var nextGeneration: Map[Int, Map[Int, Int]] = nowGeneration
drow2(nowGeneration)
for (rowIndex <- nowGeneration.zipWithIndex) {
for (cellIndex <- nowGeneration(rowIndex._2).zipWithIndex) {
val i: Int = roule(rowIndex._2, cellIndex._2, nowGeneration)
nextGeneration = nextGeneration.updated(rowIndex._2, nextGeneration(rowIndex._2).updated(cellIndex._2, i))
}
}
Thread.sleep(250);
// 次世代の処理へ
execute2(nextGeneration)
}
def drow2(generation: Map[Int, Map[Int, Int]]) {
println("")
generation map { cells =>
cells._2.values map {
case 1 => print("■")
case _ => print("□")
}
println("")
}
}
def roule(x: Int, y: Int, target: Map[Int, Map[Int, Int]]): Int = {
// ■座標の場合、◆座標から◇座標までを取得してyieldで返却し、その和をもって次世代での状態(0→死,1→生)を返却する
// 現在対象となっている座標のセルは処理しない 「if !(x == xx && y == yy))」
// ◆□□
// □■□
// □□◇
(for (xx <- List.range(x - 1, x + 2); yy <- List.range(y - 1, y + 2) if !(x == xx && y == yy)) yield {
try {
target(xx)(yy)
} catch {
case e: IndexOutOfBoundsException => 0 // 何もしない
case e: java.util.NoSuchElementException => 0
}
}).sum match {
case i if i >= 4 || i <= 1 => 0 // 死
case i if i == 3 => 1 // 誕生
case _ => target(x)(y) // 変異なし
}
}
// ブリンカー
def blinker2 = LifeGame.execute2(Map(
0 -> Map(0 -> 0,1 -> 1,2 -> 0)
,1 -> Map(0 -> 0,1 -> 1,2 -> 0)
,2 -> Map(0 -> 0,1 -> 1,2 -> 0)
))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment