game-of-life 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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