Created
December 9, 2012 17:25
-
-
Save satokitty/4246192 to your computer and use it in GitHub Desktop.
Coderetreat2012 Lifegame実装例(Scala)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package lifegame | |
import org.scalatest._ | |
import junit.JUnitRunner | |
import org.junit.runner.RunWith | |
class Board(size: (Int, Int), alivePoints: Set[(Int, Int)]) { | |
type Coordinate = (Int, Int) | |
val allCoordinates = coordinates((0, 0), (size._1 - 1, size._2 - 1)) | |
def coordinates(begin: Coordinate, end: Coordinate): Seq[Seq[Coordinate]] = | |
begin._2.to(end._2).map((col) => begin._1.to(end._1).map((_, col))) | |
def neighbors(point: Coordinate) = coordinates((point._1 - 1, point._2 - 1), (point._1 + 1, point._2 + 1)) | |
def aliveNext(point: Coordinate): Boolean = { | |
val aliveNeighborsCount = neighbors(point).flatten.filter((p) => p != point && alivePoints.contains(p)).size | |
isAlive(point) match { | |
case true => 1 < aliveNeighborsCount && aliveNeighborsCount < 4 | |
case false => aliveNeighborsCount == 3 | |
} | |
} | |
def isAlive(point: Coordinate): Boolean = point match { | |
case p: (Int, Int) if alivePoints.contains(p) => true | |
case _ => false | |
} | |
def next: Board = new Board(size, allCoordinates.flatten.filter((p) => aliveNext(p)).toSet) | |
override def toString: String = | |
allCoordinates.map((row) => | |
row.map((point) => if (isAlive(point)) "O" else "X").mkString | |
).mkString("\n") | |
} | |
@RunWith(classOf[JUnitRunner]) | |
class BoardTest extends FunSuite { | |
test("toString") { | |
val sut = new Board((3, 3), Set((0, 0), (0, 1), (1, 0))) | |
val expected = """OOX | |
|OXX | |
|XXX""".stripMargin | |
assert(sut.toString === expected) | |
} | |
test("next generation") { | |
val sut = new Board((3, 3), Set((0, 0), (0, 1), (1, 0))) | |
val actual = sut.next | |
val expected = """OOX | |
|OOX | |
|XXX""".stripMargin | |
assert(actual.toString === expected) | |
} | |
test("next generation 2") { | |
val sut = new Board((3,3), Set((0, 0), (0, 1), (0, 2))) | |
val actual = sut.next | |
val expected ="""XXX | |
|OOX | |
|XXX""".stripMargin | |
assert(actual.toString === expected) | |
} | |
/* | |
* 誕生:指定セル 死亡、隣接セル 生存数が3であった場合、次の世代では生存になる | |
* 維持:指定セル 生存、隣接セル 2 <= 生存数 <= 3の場合、次の世代では生存 | |
* 過疎:指定セル 生存、隣接セル 生存数 < 2の場合、次の世代では死亡 | |
* 過密:指定セル 生存、隣接セル 3 < 生存数の場合、次の世代では死亡 | |
*/ | |
test("セルが生存していて近傍セルの生存数が3の場合、次世代で生存") { | |
val sut = new Board((3, 3), Set((0, 0), (0, 1), (1, 0), (1, 1))) | |
assert(sut.aliveNext((0, 0)) === true) | |
} | |
test("セルが生存していて近傍セルの生存数が2の場合、次世代で生存") { | |
val sut = new Board((3, 3), Set((0, 0), (0, 1), (1, 0))) | |
assert(sut.aliveNext((0, 0)) === true) | |
} | |
test("セルが生存していて近傍セルの生存数が4以上の場合、次世代で死亡") { | |
val sut = new Board((3, 3), Set((0, 0), (0, 1), (0, 2), (1, 0), (1, 1))) | |
assert(sut.aliveNext((1, 1)) === false) | |
} | |
test("セルが死亡していて近傍セルの生存数が3以上の場合、次世代で生存") { | |
val sut = new Board((3, 3), Set((0, 0), (0, 1), (1, 0))) | |
assert(sut.aliveNext((1, 1)) === true) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment