-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcoderetreat.rb
More file actions
158 lines (125 loc) · 3.63 KB
/
Copy pathcoderetreat.rb
File metadata and controls
158 lines (125 loc) · 3.63 KB
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
require 'rspec'
require 'set'
class Space < Struct.new(:x, :y)
def neighbors
y_values = Range.new(y - 1, y + 1).to_a
x_values = Range.new(x - 1, x + 1).to_a
x_values.product(y_values).map { |x, y| Space.new(x, y) } - [Space.new(x, y)]
end
end
class Universe
attr_reader :occupied_spaces
def initialize(occupied_spaces = [])
@occupied_spaces = occupied_spaces
end
def occupy(space)
@occupied_spaces << space
end
def occupied_by_living_thing?(space)
@occupied_spaces.include?(space)
end
def occupied_neighbors(space)
space.neighbors.select{ |neighbor| occupied_by_living_thing?(neighbor)}
end
def cells_that_will_die
@occupied_spaces.select { |space| occupied_neighbors(space).count < 2 or occupied_neighbors(space).count > 3 }
end
def cells_that_will_be_born
unoccupied_neighbors.select { |space| occupied_neighbors(space).count == 3 }
end
def unoccupied_neighbors
Set.new(@occupied_spaces.map { |space| space.neighbors }.flatten) - @occupied_spaces
end
def to_s
str = ""
(-20).upto(20) { |y|
(-20).upto(20) { |x|
str << (occupied_by_living_thing?(Space.new(x, y)) ? "X" : " ")
}
str << "\n"
}
str
end
end
class GameOfLife
def self.play_turn(universe)
Universe.new(universe.occupied_spaces - universe.cells_that_will_die + universe.cells_that_will_be_born)
end
end
describe GameOfLife do
it "kills cells that have less than two neighbors" do
universe = Universe.new
universe.occupy(Space.new(0, 0))
universe.occupy(Space.new(0, 1))
next_universe = GameOfLife.play_turn(universe)
next_universe.occupied_by_living_thing?(Space.new(0, 0)).should_not be_true
next_universe.occupied_by_living_thing?(Space.new(0, 1)).should_not be_true
end
it "allows cells with two or three neighbors to live" do
universe = Universe.new
universe.occupy(Space.new(0, 0))
universe.occupy(Space.new(0, 1))
universe.occupy(Space.new(0, 2))
next_universe = GameOfLife.play_turn(universe)
next_universe.occupied_by_living_thing?(Space.new(0, 1)).should be_true
end
it "kills cells that have more than three neighbors" do
universe = Universe.new
universe.occupy(Space.new(0, 0))
universe.occupy(Space.new(0, 1))
universe.occupy(Space.new(0, 2))
universe.occupy(Space.new(1, 0))
universe.occupy(Space.new(1, 1)) # will die
next_universe = GameOfLife.play_turn(universe)
next_universe.occupied_by_living_thing?(Space.new(1, 1)).should_not be_true
end
it "births cells that has exactly three neighbors" do
universe = Universe.new
universe.occupy(Space.new(0, 0))
universe.occupy(Space.new(0, 1))
universe.occupy(Space.new(0, 2))
next_universe = GameOfLife.play_turn(universe)
next_universe.occupied_by_living_thing?(Space.new(1, 1)).should be_true
end
end
describe Universe do
it "can occupy spaces" do
universe = Universe.new
space = Space.new(0, 1)
universe.occupy(space)
universe.occupied_by_living_thing?(space).should be_true
end
it "finds occupied neighbors for a given space" do
universe = Universe.new
universe.occupy(Space.new(0, 0))
universe.occupy(Space.new(0, 1))
universe.occupied_neighbors(Space.new(1, 1)).should =~ [
Space.new(0, 0),
Space.new(0, 1)
]
end
end
describe Space do
it "knows its neighbors" do
space = Space.new(1, 1)
space.neighbors.should =~ [
Space.new(0, 0),
Space.new(1, 0),
Space.new(2, 0),
Space.new(0, 1),
Space.new(2, 1),
Space.new(0, 2),
Space.new(1, 2),
Space.new(2, 2)
]
end
end
universe = Universe.new
universe.occupy(Space.new(0, 0))
universe.occupy(Space.new(0, 1))
universe.occupy(Space.new(0, 2))
loop {
puts universe.to_s
universe = GameOfLife.play_turn(universe)
sleep 2
}