-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathgameOfLife.scala
125 lines (99 loc) · 2.88 KB
/
gameOfLife.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
class Cell(alive: Boolean ) {
var isAlive: Boolean = alive
override def toString = if (this isAlive) "x" else "-"
def isDead = !this.isAlive
}
object Grid {
val width: Int = 10
val height: Int = 10
var grid = new Array[Array[Cell]](width, height)
iterGrid((x, y) => {
if (x == 0 && y == 0) grid(x)(y) = new Cell(true)
else if (x == 1 && y == 1) grid(x)(y) = new Cell(true)
else if (x == 2 && y == 2) grid(x)(y) = new Cell(true)
else grid(x)(y) = new Cell(false)
}, Unit => Unit)
private def iterGrid(inner: (Int, Int) => Unit, outer: Unit => Unit) {
for (y <- 0 to height - 1) {
for (x <- 0 to width - 1) {
inner(x, y)
}
outer()
}
}
// TODO fix so that new grid is calculated from old grid, calculating
// in place leads to side effects
def goToNextStep = {
iterGrid((x, y) => {
val aCell = grid(x)(y)
val numberOfAliveNeighbors = numberOfAliveNeighborsOfCellAt(x, y)
if (aCell isAlive) {
println("Cell (" + x + ", " + y + ") is alive")
println("Number of alive neighbors: " + numberOfAliveNeighbors)
if (numberOfAliveNeighbors < 2) kill(aCell)
else if (numberOfAliveNeighbors > 3) kill(aCell)
}
else if (numberOfAliveNeighbors == 3) resurrect(aCell)
}, Unit => Unit)
}
def numberOfAliveNeighborsOfCellAt(x: Int, y: Int): Int = {
var numberOfAliveNeighbors: Int = 0
iterNeighbors((x, y) => if (grid(x)(y) isAlive) numberOfAliveNeighbors += 1,
x, y)
return numberOfAliveNeighbors
}
def iterNeighbors(f: (Int, Int) => Unit, x: Int, y: Int) = {
def cellExists(x: Int, y: Int): Boolean = {
if ((x >= 0 && x <= (width - 1))
&& (y >= 0 && y <= (height - 1)))
{
return true;
}
else return false;
}
// top left
if (cellExists(x-1, y-1)) f(x-1,y-1)
// top center
if (cellExists(x, y-1)) f(x,y-1)
// top right
if (cellExists(x+1, y-1)) f(x+1,y-1)
// middle left
if (cellExists(x-1, y)) f(x-1,y)
// middle right
if (cellExists(x+1, y)) f(x+1,y)
// bottom left
if (cellExists(x-1, y+1)) f(x-1,y+1)
// bottom center
if (cellExists(x, y+1)) f(x,y+1)
// bottom right
if (cellExists(x+1, y+1)) f(x+1,y+1)
}
def kill(aCell: Cell) = aCell isAlive = false
def resurrect(aCell: Cell) = aCell isAlive = true
def isNotDead: Boolean = {
var isDead = true
iterGrid((x,y) => {
if (grid(x)(y).isAlive) isDead = false
}, Unit => Unit)
return !isDead
}
override def toString = {
var gridStr = ""
iterGrid((x,y) => {
gridStr = gridStr + grid(x)(y)
}, Unit => {gridStr = gridStr + "\n"})
gridStr
}
}
object Main {
def main(args: Array[String]) {
do
{
print(Grid)
Grid goToNextStep
readLine("Go to next step? ");
}
while (Grid isNotDead)
print(Grid)
}
}