game-of-life 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ NTdhOTY3OTFmZWFjZTdhM2IwNzc5MzliMTY4NTBkOWFiM2IxMGE1Nw==
5
+ data.tar.gz: !binary |-
6
+ ZTc2ZDBlNjM5OTBlOGJjYzczMjYyYTZjM2U3ZDJiY2RiMjNiY2NkMw==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ ZmU2NDQ4YzU1OGEyYzY4YmEwNzI3MTU4YjliZjAyMjFlNWU4NGEwMzc1MzYz
10
+ YzRjNzhiZTY3YzEzYzI5OWE2OGY5OTUxNTU3MWY2M2JlZDM1YWQ0MDdmMzI3
11
+ MDBjYzAzMzE5OTdiMjc5OWI5MjZjNmZiZWY0ODk0MjQ3MjBkYzM=
12
+ data.tar.gz: !binary |-
13
+ NDc3YTQxNjE2ZWFmZDk1ZjdhNjA3YjhmNjMxMmIxNTc5MGVmNGY1YzkwZWUw
14
+ NzY0ZDBlMjE4MzRmN2UzZDY3YTUwY2RmZDU4MzU3NDcyYTdkNzQ3Y2EwNWI0
15
+ MjI4MjVlOGFmMjBhOTI3ZGEzMTY2NWRlYTQ0YWYzNjgzNzk3Zjg=
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ ruby-1.9.3-p448
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,18 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ game-of-life (0.1.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ gosu (0.7.50)
10
+ rake (0.9.2.2)
11
+
12
+ PLATFORMS
13
+ ruby
14
+
15
+ DEPENDENCIES
16
+ game-of-life!
17
+ gosu
18
+ rake
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new(:test) do |test|
5
+ test.libs << 'lib' << 'test'
6
+ test.pattern = 'test/**/*_test.rb'
7
+ test.verbose = true
8
+ end
9
+
10
+ task :default => :test
data/bin/game-of-life ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../lib/game_of_life'
4
+
5
+ raise RubyVersionException unless RUBY_VERSION == "1.9.3"
6
+
7
+ GameOfLife::GameOfLifeWindow.new(800,600).show
8
+
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'game-of-life/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "game-of-life"
8
+ gem.version = GameOfLife::VERSION
9
+ gem.authors = ["Thiago Rocha"]
10
+ gem.email = ["kimo@kimo.io"]
11
+ gem.description = %q{The Game of Life}
12
+ gem.summary = %q{A gem that shows random matches of Conway's Game of Life }
13
+ gem.homepage = "http://thiagokimo.github.io/game-of-life"
14
+
15
+ gem.license = 'MIT'
16
+
17
+ gem.files = `git ls-files`.split($/)
18
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
19
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
20
+ gem.require_paths = ["lib"]
21
+ gem.add_development_dependency 'rake'
22
+
23
+ gem.add_dependency 'gosu'
24
+ end
@@ -0,0 +1,33 @@
1
+ module GameOfLife
2
+ class Cell
3
+ attr_accessor :x, :y, :alive, :neighbours
4
+ def initialize(x=0,y=0,alive=true)
5
+ @x,@y = x,y
6
+ @alive = alive
7
+ end
8
+
9
+ def ==(otherCell)
10
+ (self.x == otherCell.x) and (self.y == otherCell.y)
11
+ end
12
+
13
+ def neighbours
14
+ []
15
+ end
16
+
17
+ def alive?
18
+ self.alive
19
+ end
20
+
21
+ def dead?
22
+ not alive?
23
+ end
24
+
25
+ def reborn!
26
+ @alive = true
27
+ end
28
+
29
+ def die!
30
+ @alive = false
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,2 @@
1
+ class GameOfLifeException < StandardError ; end
2
+ class RubyVersionException < GameOfLifeException ; end
@@ -0,0 +1,6 @@
1
+ module GameOfLife
2
+ MAJOR = 0
3
+ MINOR = 1
4
+ PATCH = 1
5
+ VERSION = "#{MAJOR}.#{MINOR}.#{PATCH}"
6
+ end
@@ -0,0 +1,316 @@
1
+ require 'matrix'
2
+
3
+ module GameOfLife
4
+ class World
5
+ attr_accessor :cells, :board
6
+
7
+ def initialize(width,height)
8
+ @width, @height = width, height
9
+ setup(false)
10
+ end
11
+
12
+ def seed!
13
+ clean_cells
14
+ setup(true)
15
+ end
16
+
17
+ def live_cells
18
+ @cells.select { |cell| cell.alive? }
19
+ end
20
+
21
+ def dead_cells
22
+ @cells.select { |cell| cell.dead? }
23
+ end
24
+
25
+ def kill(x,y)
26
+ @board.element(x,y).die!
27
+ end
28
+
29
+ def get(x,y)
30
+ @board.element(x,y)
31
+ end
32
+
33
+ def revive(x,y)
34
+ @board.element(x,y).reborn!
35
+ end
36
+
37
+ def live_neighbours_of(x,y)
38
+ live_neighbours = []
39
+
40
+ # up-left
41
+ if x-1 >= 0 and y+1 <= @height-1
42
+ neighbour = get(x-1,y+1)
43
+ live_neighbours << neighbour if neighbour.alive?
44
+ end
45
+
46
+ # up
47
+ if y+1 <= @height-1
48
+ neighbour = get(x,y+1)
49
+ live_neighbours << neighbour if neighbour.alive?
50
+ end
51
+
52
+ # up-right
53
+ if x+1 <= @width-1 and y+1 <= @height-1
54
+ neighbour = get(x+1,y+1)
55
+ live_neighbours << neighbour if neighbour.alive?
56
+ end
57
+
58
+ # left
59
+ if x-1 >= 0
60
+ neighbour = get(x-1,y)
61
+ live_neighbours << neighbour if neighbour.alive?
62
+ end
63
+
64
+ # right
65
+ if x+1 <= @width-1
66
+ neighbour = get(x+1,y)
67
+ live_neighbours << neighbour if neighbour.alive?
68
+ end
69
+
70
+ # down-left
71
+ if x-1 >= 0 and y-1 >= 0
72
+ neighbour = get(x-1,y-1)
73
+ live_neighbours << neighbour if neighbour.alive?
74
+ end
75
+
76
+ # down
77
+ if y-1 >= 0
78
+ neighbour = get(x,y-1)
79
+ live_neighbours << neighbour if neighbour.alive?
80
+ end
81
+
82
+ # down-right
83
+ if x+1 <= @width-1 and y-1 >= 0
84
+ neighbour = get(x+1,y-1)
85
+ live_neighbours << neighbour if neighbour.alive?
86
+ end
87
+
88
+ live_neighbours
89
+ end
90
+
91
+ def rotate!
92
+ future_alive_cells = []
93
+ future_dead_cells = []
94
+
95
+ @cells.each do |cell|
96
+ live_neighbours = live_neighbours_of(cell.x,cell.y)
97
+
98
+ future_dead_cells << cell if apply_rule_1(cell,live_neighbours)
99
+ future_alive_cells << cell if apply_rule_2(cell,live_neighbours)
100
+ future_dead_cells << cell if apply_rule_3(cell,live_neighbours)
101
+ future_alive_cells << cell if apply_rule_4(cell,live_neighbours)
102
+ end
103
+
104
+ update_board(future_alive_cells,future_dead_cells)
105
+ update_cells
106
+ end
107
+
108
+ private
109
+ def apply_rule_1(cell,live_neighbours)
110
+ cell.alive? and live_neighbours.count < 2
111
+ end
112
+
113
+ def apply_rule_2(cell,live_neighbours)
114
+ cell.alive? and (live_neighbours.count == 2 or live_neighbours.count == 3)
115
+ end
116
+
117
+ def apply_rule_3(cell,live_neighbours)
118
+ cell.alive? and live_neighbours.count > 3
119
+ end
120
+
121
+ def apply_rule_4(cell,live_neighbours)
122
+ cell.dead? and live_neighbours.count == 3
123
+ end
124
+
125
+ def rebuild_board(live_cells,dead_cells)
126
+ (live_cells+dead_cells).each do |cell|
127
+ @board.set(cell.x,cell.y,cell)
128
+ end
129
+ end
130
+
131
+ def setup(random)
132
+ @board = Matrix.build(@width, @height) { |row,column|
133
+ if random
134
+ cell = Cell.new(row,column,[true,false].sample)
135
+ else
136
+ cell = Cell.new(row,column)
137
+ end
138
+ }
139
+
140
+ update_cells
141
+ end
142
+
143
+ def update_board(to_live,to_die)
144
+ to_live.each do |cell|
145
+ revive(cell.x,cell.y)
146
+ end
147
+ to_die.each do |cell|
148
+ kill(cell.x,cell.y)
149
+ end
150
+ end
151
+
152
+ def update_cells
153
+ @cells = @board.to_a.flatten!
154
+ end
155
+
156
+ def clean_cells
157
+ @cells = nil
158
+ @board = nil
159
+ end
160
+ end
161
+ # class World
162
+ # attr_accessor :cells, :board
163
+ # attr_reader :width, :height
164
+
165
+ # def initialize(width=10, height=10, allow_negative_cells=true)
166
+ # @width, @height = width, height
167
+ # @negative = allow_negative_cells
168
+ # @cells = []
169
+
170
+ # setup_board
171
+ # end
172
+
173
+ # def dead_cells
174
+ # @cells.select { |cell| cell.dead? }
175
+ # end
176
+
177
+ # def live_cells
178
+ # @cells.select { |cell| cell.alive? }
179
+ # end
180
+
181
+ # def seed!
182
+ # for x in (0).upto(@width-1) do
183
+ # for y in (0).upto(@height-1) do
184
+ # cell = Cell.new(x,y,[true,false].sample)
185
+ # @cells << cell
186
+ # @board[x][y] = cell
187
+ # end
188
+ # end
189
+ # end
190
+
191
+ # # up_left | up | up_right
192
+ # # ----------|------|-----------
193
+ # # left | cell | right
194
+ # # ----------|------|-----------
195
+ # # down_left | down | down_right
196
+ # def live_neighbours_of(cell)
197
+ # live_neighbours = []
198
+
199
+ # up_left = Cell.new(cell.x-1,cell.y+1)
200
+ # up = Cell.new(cell.x,cell.y+1)
201
+ # up_right = Cell.new(cell.x+1,cell.y+1)
202
+ # left = Cell.new(cell.x-1,cell.y)
203
+ # right = Cell.new(cell.x+1,cell.y)
204
+ # down_left = Cell.new(cell.x-1,cell.y-1)
205
+ # down = Cell.new(cell.x,cell.y-1)
206
+ # down_right = Cell.new(cell.x+1,cell.y-1)
207
+
208
+ # neighbour_candidates = [up_left,up,up_right,left,right,down_left,down,down_right]
209
+
210
+ # neighbour_candidates.each do |neighbour|
211
+ # live_neighbours << @board[neighbour.x][neighbour.y] if not outside_of_the_world?(neighbour) and neighbour.alive?
212
+ # end
213
+
214
+ # live_neighbours
215
+ # end
216
+
217
+ # def exist?(cell)
218
+ # @cells.include? cell
219
+ # end
220
+
221
+ # def rotate!
222
+ # future_alive_cells = []
223
+ # future_dead_cells = []
224
+
225
+ # @cells.each do |cell|
226
+ # num_live_neighbours = live_neighbours_of(cell).count
227
+
228
+ # # Rule #1
229
+ # if cell.alive? and num_live_neighbours < 2
230
+ # future_dead_cells << cell
231
+ # end
232
+
233
+ # # Rule #2
234
+ # if live_neighbours_of(cell).count == 2 or live_neighbours_of(cell).count == 3
235
+ # future_alive_cells << cell
236
+ # end
237
+
238
+ # # Rule #3
239
+ # if cell.alive? and num_live_neighbours > 3
240
+ # future_dead_cells << cell
241
+ # end
242
+
243
+ # # Rule #4
244
+ # if cell.dead? and num_live_neighbours == 3
245
+ # future_alive_cells << cell
246
+ # end
247
+
248
+ # update_cells(future_alive_cells,future_dead_cells)
249
+ # end
250
+ # end
251
+
252
+ # def create(cell)
253
+ # # raise CellAlreadyExistsInTheWorldException if exist?(cell)
254
+ # raise CellInvalidCoordinatesException if outside_of_the_world?(cell) or negative_coordinates?(cell)
255
+ # @cells << cell
256
+ # end
257
+
258
+ # def revive(cell)
259
+ # raise CellIsAlreadyAliveException if exist?(cell) and cell.alive?
260
+ # cell.reborn!
261
+ # end
262
+
263
+ # def kill(cell)
264
+ # raise CellIsAlreadyDeadException if exist?(cell) and cell.dead?
265
+ # cell.die!
266
+ # end
267
+
268
+ # private
269
+ # def setup_board
270
+ # @board = Array.new(@width) do |row|
271
+ # Array.new(@height) do |column|
272
+ # Cell.new(row,column)
273
+ # end
274
+ # end
275
+
276
+ # @board.each do |row|
277
+ # row.each do |column|
278
+ # @cells << column
279
+ # end
280
+ # end
281
+ # end
282
+
283
+ # def update_cells(alives,deads)
284
+ # alives.each do |cell|
285
+ # cell.reborn!
286
+ # end
287
+ # deads.each do |cell|
288
+ # cell.die!
289
+ # end
290
+ # end
291
+
292
+ # def apply_rule_1(cell,number_of_live_neighbours)
293
+ # kill(cell) if cell.alive? and number_of_live_neighbours < 2
294
+ # end
295
+
296
+ # def apply_rule_2(cell)
297
+ # # revive(cell) if live_neighbours_of(cell).count == 2 or live_neighbours_of(cell).count == 3
298
+ # end
299
+
300
+ # def apply_rule_3(cell,number_of_live_neighbours)
301
+ # kill(cell) if cell.alive? and number_of_live_neighbours > 3
302
+ # end
303
+
304
+ # def apply_rule_4(cell,number_of_live_neighbours)
305
+ # revive(cell) if cell.dead? and number_of_live_neighbours == 3
306
+ # end
307
+
308
+ # def outside_of_the_world?(cell)
309
+ # (cell.x > @width) or (cell.y > @height)
310
+ # end
311
+
312
+ # def negative_coordinates?(cell)
313
+ # (cell.x < 0) or (cell.y < 0) and not @negative
314
+ # end
315
+ # end
316
+ end
@@ -0,0 +1,60 @@
1
+ require_relative 'game-of-life/exceptions'
2
+ require_relative 'game-of-life/cell'
3
+ require_relative 'game-of-life/world'
4
+ require_relative 'game-of-life/version'
5
+ require 'gosu'
6
+
7
+ module GameOfLife
8
+ class GameOfLifeWindow < Gosu::Window
9
+ def initialize(width=640, height=480)
10
+ @width, @height = width, height
11
+ super(@width, @height, false)
12
+ self.caption = 'The Game of Life'
13
+
14
+ # Variables
15
+ @num_columns = @width/5
16
+ @num_rows = @height/5
17
+ @column_width = @width/@num_columns
18
+ @row_height = @height/@num_rows
19
+
20
+ @white_color = Gosu::Color.new(0xffffffff)
21
+ @black_color = Gosu::Color.new(0xff000000)
22
+ @dead_color = Gosu::Color.new(0xff808080)
23
+
24
+ @world = World.new(@num_columns,@num_rows)
25
+ @world.seed!
26
+ end
27
+
28
+ def update
29
+ @world.rotate!
30
+ end
31
+
32
+ def draw
33
+ draw_cells
34
+ end
35
+
36
+ def needs_cursor?
37
+ true
38
+ end
39
+
40
+ def draw_cells
41
+ @world.cells.each do |cell|
42
+ if cell.alive?
43
+ draw_quad(
44
+ cell.x * @column_width, cell.y * @row_height, @white_color,
45
+ cell.x * @column_width + @column_width, cell.y * @row_height, @white_color,
46
+ cell.x * @column_width + @column_width, cell.y * @row_height + @row_height, @white_color,
47
+ cell.x * @column_width, cell.y * @row_height + @row_height, @white_color
48
+ )
49
+ else
50
+ draw_quad(
51
+ cell.x * @column_width, cell.y * @row_height, @black_color,
52
+ cell.x * @column_width + @column_width, cell.y * @row_height, @black_color,
53
+ cell.x * @column_width + @column_width, cell.y * @row_height + @row_height, @black_color,
54
+ cell.x * @column_width, cell.y * @row_height + @row_height, @black_color
55
+ )
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,62 @@
1
+ require_relative '../../test_helper'
2
+
3
+ module GameOfLife
4
+ describe Cell do
5
+ describe "coordinates" do
6
+ it "coordinates" do
7
+ cell = Cell.new
8
+ cell.x.wont_be_nil
9
+ cell.y.wont_be_nil
10
+ end
11
+ it "should store coordinates" do
12
+ random_x = rand(11)
13
+ random_y = rand(11)
14
+
15
+ cell = Cell.new(random_x,random_y)
16
+
17
+ cell.x.must_equal random_x
18
+ cell.y.must_equal random_y
19
+ end
20
+ end
21
+
22
+ describe "==" do
23
+ it "should be true if 2 cells has the same coordinates" do
24
+ cell_1 = Cell.new(1,2)
25
+ cell_2 = Cell.new(1,2)
26
+
27
+ cell_1.must_equal cell_2
28
+ end
29
+
30
+ it "should be false if 2 cells has different coordinates" do
31
+ cell_1 = Cell.new(1,2)
32
+ cell_2 = Cell.new(2,1)
33
+
34
+ cell_1.wont_equal cell_2
35
+ end
36
+ end
37
+
38
+ it "should be able to die" do
39
+ cell = Cell.new
40
+
41
+ cell.die!
42
+ cell.dead?.must_equal true
43
+ end
44
+
45
+ it "should be able to reborn" do
46
+ cell = Cell.new(0,0,false)
47
+
48
+ cell.reborn!
49
+ cell.alive?.must_equal true
50
+ end
51
+
52
+ it "should be dead or alive" do
53
+ cell = Cell.new
54
+ cell.alive.wont_be_nil
55
+ end
56
+
57
+ it "must have neighbours cells" do
58
+ cell = Cell.new
59
+ cell.neighbours.wont_be_nil
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,85 @@
1
+ require_relative '../../test_helper'
2
+
3
+ module GameOfLife
4
+ describe World do
5
+ describe "#initialize" do
6
+ it "should have a collection of cells" do
7
+ world = World.new(1,1)
8
+
9
+ world.cells.wont_be_nil
10
+ end
11
+
12
+ it "number of cells must be its width multiplied per its height" do
13
+ world = World.new(5,3)
14
+ world.cells.count.must_equal 5*3
15
+ end
16
+
17
+ it "must setup a matrix of cells, that represents the game board" do
18
+ world = World.new(3,3)
19
+
20
+ world.board.must_be_kind_of(Matrix)
21
+ end
22
+ end
23
+
24
+ it "should be able to randomize some cells" do
25
+ world = World.new(10,10)
26
+
27
+ world.seed!
28
+
29
+ world.live_cells.count.must_be(:>,0)
30
+ world.dead_cells.count.must_be(:>,0)
31
+ end
32
+
33
+ describe "#live_neighbours_of" do
34
+ it "should be able to count the live neighbours of a cell" do
35
+ world = World.new(3,3)
36
+
37
+ world.kill(0,0)
38
+ world.kill(1,0)
39
+
40
+ world.live_neighbours_of(1,1).count.must_equal 6
41
+ end
42
+
43
+ it "the cell (0,0) must have only 3 live neighbours" do
44
+ world = World.new(3,3)
45
+
46
+ world.live_neighbours_of(0,0).count.must_equal 3
47
+ end
48
+ end
49
+
50
+ describe "#make_it_live" do
51
+ it "should be able to make a dead cell live" do
52
+ world = World.new(2,2)
53
+
54
+ world.kill(1,1)
55
+ world.get(1,1).dead?.must_equal true
56
+
57
+ world.revive(1,1)
58
+ world.get(1,1).dead?.must_equal false
59
+ end
60
+ end
61
+
62
+ describe "#get" do
63
+ it "should return a given cell" do
64
+ world = World.new(2,2)
65
+
66
+ cell_to_be_found = Cell.new(1,1)
67
+
68
+ found_cell = world.get(1,1)
69
+
70
+ found_cell.must_equal cell_to_be_found
71
+ end
72
+ end
73
+
74
+ describe "#kill" do
75
+ it "should be able to kill a cell" do
76
+ world = World.new(2,2)
77
+
78
+ world.dead_cells.count.must_equal 0
79
+ world.kill(1,1)
80
+
81
+ world.dead_cells.count.must_equal 1
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,35 @@
1
+ require_relative '../test_helper'
2
+
3
+ module GameOfLife
4
+ describe "Rule #1: Any live cell with fewer than two live neighbours dies, as if caused by under-population." do
5
+ it "cells with 1 neighbour dies in the next day" do
6
+ world = World.new(2,2)
7
+
8
+ world.kill(0,0)
9
+ world.kill(1,1)
10
+
11
+ world.rotate!
12
+
13
+ world.cells.each do |cell|
14
+ cell.dead?.must_equal true
15
+ end
16
+ end
17
+
18
+ it "a cell with no live neighbours should die in the next day" do
19
+ world = World.new(3,3)
20
+
21
+ world.kill(0,0)
22
+ world.kill(1,0)
23
+ world.kill(2,0)
24
+ world.kill(0,1)
25
+ world.kill(2,1)
26
+ world.kill(0,2)
27
+ world.kill(1,2)
28
+ world.kill(2,2)
29
+
30
+ world.rotate!
31
+
32
+ world.get(1,1).dead?.must_equal true
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,24 @@
1
+ require_relative '../test_helper'
2
+
3
+ module GameOfLife
4
+ describe "Rule #4: Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction." do
5
+ it "a dead cell with 3 live neighbours will reborn in the next day" do
6
+ world = World.new(3,3)
7
+
8
+ # (0,2) (1,2) (2,2)
9
+ # (0,1) (1,1) (2,1)
10
+ # (0,0) (1,0) (2,0)
11
+
12
+ world.kill(1,2)
13
+ world.kill(2,2)
14
+ world.kill(2,1)
15
+ world.kill(2,0)
16
+ world.kill(1,0)
17
+ world.kill(1,1)
18
+
19
+ world.rotate!
20
+
21
+ world.get(1,1).alive?.must_equal true
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,33 @@
1
+ require_relative '../test_helper'
2
+
3
+ module GameOfLife
4
+ describe "Rule #2: Any live cell with two or three live neighbours lives on to the next generation." do
5
+ it "a cell with 2 live neighbours will be alive in the next day" do
6
+ world = World.new(3,3)
7
+
8
+ world.kill(0,2)
9
+ world.kill(1,2)
10
+ world.kill(2,2)
11
+ world.kill(0,0)
12
+ world.kill(1,0)
13
+ world.kill(2,0)
14
+
15
+ world.rotate!
16
+
17
+ world.get(1,1).alive?.must_equal true
18
+ end
19
+
20
+ it "a cell with 3 live neighbours will be alive in the next day" do
21
+ world = World.new(3,3)
22
+
23
+ world.kill(1,1)
24
+ world.kill(2,1)
25
+ world.kill(1,0)
26
+ world.kill(2,0)
27
+
28
+ world.rotate!
29
+
30
+ world.get(0,2).alive?.must_equal true
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,26 @@
1
+ require_relative '../test_helper'
2
+
3
+ module GameOfLife
4
+ describe "Rule #3: Any live cell with more than three live neighbours dies, as if by overcrowding." do
5
+ it "a cell with 4 live neighbours will die in the next day" do
6
+ world = World.new(3,3)
7
+
8
+ world.kill(0,2)
9
+ world.kill(1,2)
10
+ world.kill(2,2)
11
+ world.kill(2,0)
12
+
13
+ world.rotate!
14
+
15
+ world.get(1,1).dead?.must_equal true
16
+ end
17
+
18
+ it "a cell surrounded by live neighbours must die in the next day" do
19
+ world = World.new(3,3)
20
+
21
+ world.rotate!
22
+
23
+ world.get(1,1).dead?.must_equal true
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,2 @@
1
+ require 'minitest/autorun'
2
+ require File.expand_path('../../lib/game_of_life.rb', __FILE__)
metadata ADDED
@@ -0,0 +1,98 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: game-of-life
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Thiago Rocha
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-11-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ! '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ! '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: gosu
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: The Game of Life
42
+ email:
43
+ - kimo@kimo.io
44
+ executables:
45
+ - game-of-life
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - .ruby-version
50
+ - Gemfile
51
+ - Gemfile.lock
52
+ - Rakefile
53
+ - bin/game-of-life
54
+ - game-of-life.gemspec
55
+ - lib/game-of-life/cell.rb
56
+ - lib/game-of-life/exceptions.rb
57
+ - lib/game-of-life/version.rb
58
+ - lib/game-of-life/world.rb
59
+ - lib/game_of_life.rb
60
+ - test/lib/game-of-life/cell_test.rb
61
+ - test/lib/game-of-life/world_test.rb
62
+ - test/rules/first_rule_test.rb
63
+ - test/rules/fourth_rule_test.rb
64
+ - test/rules/second_rule_test.rb
65
+ - test/rules/third_rule_test.rb
66
+ - test/test_helper.rb
67
+ homepage: http://thiagokimo.github.io/game-of-life
68
+ licenses:
69
+ - MIT
70
+ metadata: {}
71
+ post_install_message:
72
+ rdoc_options: []
73
+ require_paths:
74
+ - lib
75
+ required_ruby_version: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ! '>='
78
+ - !ruby/object:Gem::Version
79
+ version: '0'
80
+ required_rubygems_version: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ! '>='
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
85
+ requirements: []
86
+ rubyforge_project:
87
+ rubygems_version: 2.1.10
88
+ signing_key:
89
+ specification_version: 4
90
+ summary: A gem that shows random matches of Conway's Game of Life
91
+ test_files:
92
+ - test/lib/game-of-life/cell_test.rb
93
+ - test/lib/game-of-life/world_test.rb
94
+ - test/rules/first_rule_test.rb
95
+ - test/rules/fourth_rule_test.rb
96
+ - test/rules/second_rule_test.rb
97
+ - test/rules/third_rule_test.rb
98
+ - test/test_helper.rb