-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathUniverse.go
65 lines (50 loc) · 1.39 KB
/
Universe.go
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
package gameoflife
import "fmt"
// Universe in a Game of Life
type Universe struct {
rules Rules
life PointSet
}
// Next calculates the next generation of the Universe.
func (u *Universe) Next() *Universe {
return &Universe{
rules: u.rules,
life: u.cellsOfNextGeneration(),
}
}
func (u *Universe) cellsOfNextGeneration() PointSet {
return Union(u.survivingCells(), u.bornCells())
}
func (u *Universe) survivingCells() PointSet {
return u.life.Filter(u.survives)
}
func (u *Universe) bornCells() PointSet {
return u.deadNeighborsOfLivingCells().Filter(u.born)
}
func (u *Universe) deadNeighborsOfLivingCells() PointSet {
return u.life.FlatMap(u.deadNeighbors)
}
func (u *Universe) survives(cell *Point) bool {
return u.rules.Survives(u.countLiveNeighbors(cell))
}
func (u *Universe) born(cell *Point) bool {
return u.rules.Born(u.countLiveNeighbors(cell))
}
func (u *Universe) isAlive(cell *Point) bool {
return u.life[*cell]
}
func (u *Universe) isDead(cell *Point) bool {
return !u.life[*cell]
}
func (u *Universe) deadNeighbors(cell *Point) PointSet {
return cell.neighbors().Filter(u.isDead)
}
func (u *Universe) liveNeighbors(cell *Point) PointSet {
return cell.neighbors().Filter(u.isAlive)
}
func (u *Universe) countLiveNeighbors(cell *Point) int {
return len(u.liveNeighbors(cell))
}
func (u *Universe) String() string {
return fmt.Sprintf("Universe{%s\n%s}", u.rules, u.life)
}