-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgol.st
82 lines (71 loc) · 2.09 KB
/
gol.st
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
Object subclass: GameOfLife [
| cells |
<comment:'I model the game of life. I am basically a matrix of cells being either alive (true) or dead (false). I am able to compute my next state depending on my current state using #next method.'>
GameOfLife class >> extent: aPoint [
<category: 'instance creation'>
^ self new
cells: ((1 to: aPoint x) collect: [ :i |
Array new: aPoint y withAll: false ]);
yourself
]
cells [
<category: 'private'>
^ cells
]
cells: anObject [
<category: 'private'>
cells := anObject
]
isAliveAt: x at: y [
<category: 'testing'>
^ [
(self cells at: x) at: y
] on: SystemExceptions.IndexOutOfRange do: [ false ]
]
printOn: aStream [
<category: 'printing'>
(1 to: self extent y) do: [ :y |
1 to: self extent x do: [ :x |
(self isAliveAt: x at: y)
ifTrue: [ aStream nextPut: $# ]
ifFalse: [ aStream nextPut: Character space ] ] ] separatedBy: [ aStream << Character lf ]
]
cellAt: x at: y beAlive: aBoolean [
<category: 'accessing'>
^ (self cells at: x) at: y put: aBoolean
]
neighbourhoodCoordinatesOfCellAt: x at: y [
<category: 'accessing'>
^ {-1 @ 1. 0 @ 1 . 1 @ 1.
-1 @ 0. 1 @ 0.
-1 @ -1. 0 @ -1. 1 @ -1
} collect: [ :toAdd | (x@y) + toAdd ]
]
neighbourhoodOfCellAt: x at: y [
<category: 'accessing'>
^ (self neighbourhoodCoordinatesOfCellAt: x at: y) collect: [ :p |
self isAliveAt: p x at: p y ]
]
next [
<category: 'computation'>
| nextGrid |
nextGrid := self class extent: self extent.
"Fill the next world with new values."
1 to: self extent x do: [ :x |
1 to: self extent y do: [ :y |
|aliveNeighboors|
aliveNeighboors := (self neighbourhoodOfCellAt: x at: y) select: [ :b | b = true ].
(((self isAliveAt: x at: y) and: [ (aliveNeighboors size between: 2 and: 3) ])
or: [ (self isAliveAt: x at: y) not and: [ (aliveNeighboors size = 3) ] ])
ifTrue: [
nextGrid
cellAt: x
at: y
beAlive: true ] ] ].
^ nextGrid
]
extent [
<category: 'accessing'>
^ self cells size @ self cells first size
]
]