gol 0.2
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.
- data/bin/gol +8 -0
- data/lib/cell.rb +27 -0
- data/lib/game.rb +73 -0
- data/lib/gol.rb +78 -0
- data/lib/grid.rb +159 -0
- data/lib/spec/cell_spec.rb +52 -0
- data/lib/spec/game_spec.rb +32 -0
- data/lib/spec/grid_spec.rb +399 -0
- metadata +54 -0
data/bin/gol
ADDED
data/lib/cell.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
module Gol
|
2
|
+
class Cell
|
3
|
+
attr_accessor :alive, :will_live, :x, :y
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@alive = false
|
7
|
+
@will_live = false
|
8
|
+
end
|
9
|
+
|
10
|
+
def alive?
|
11
|
+
@alive
|
12
|
+
end
|
13
|
+
|
14
|
+
def kill
|
15
|
+
@alive = false
|
16
|
+
end
|
17
|
+
|
18
|
+
def set_alive
|
19
|
+
@alive = true
|
20
|
+
end
|
21
|
+
|
22
|
+
def will_live?
|
23
|
+
@will_live
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
data/lib/game.rb
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
require_relative 'grid'
|
2
|
+
|
3
|
+
module Gol
|
4
|
+
class Game
|
5
|
+
attr_accessor :grid, :pause
|
6
|
+
|
7
|
+
def initialize(size, pause)
|
8
|
+
@pause = pause
|
9
|
+
@grid = Grid.new(size)
|
10
|
+
end
|
11
|
+
|
12
|
+
|
13
|
+
def print_game
|
14
|
+
puts
|
15
|
+
str = ""
|
16
|
+
@grid.each do |cell|
|
17
|
+
if cell.x == 1 and cell.alive?
|
18
|
+
str += "|O|"
|
19
|
+
elsif cell.x == 1 and !cell.alive?
|
20
|
+
str += "|_|"
|
21
|
+
elsif cell.x == grid.size and cell.alive?
|
22
|
+
str += "O|\n"
|
23
|
+
elsif cell.x == grid.size and !cell.alive?
|
24
|
+
str += "_|\n"
|
25
|
+
elsif cell.alive?
|
26
|
+
str += "O|"
|
27
|
+
else
|
28
|
+
str += "_|"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
puts str
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
def step
|
36
|
+
print_game
|
37
|
+
@grid.cells.each do |cell|
|
38
|
+
@grid.check_survival(cell)
|
39
|
+
end
|
40
|
+
@grid.cells.each do |cell|
|
41
|
+
if cell.will_live?
|
42
|
+
cell.set_alive
|
43
|
+
else
|
44
|
+
cell.kill
|
45
|
+
end
|
46
|
+
end
|
47
|
+
print_game
|
48
|
+
sleep @pause
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
|
53
|
+
def turn_alive_random_cells
|
54
|
+
max_cells = rand(@grid.cells.size)
|
55
|
+
cells_to_live = []
|
56
|
+
max_cells.times do
|
57
|
+
cells_to_live << @grid.cells.sample
|
58
|
+
end
|
59
|
+
cells_to_live.each do |c|
|
60
|
+
c.set_alive
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def glider
|
65
|
+
@grid.get_cell(6, 5).set_alive
|
66
|
+
@grid.get_cell(7, 6).set_alive
|
67
|
+
@grid.get_cell(5, 7).set_alive
|
68
|
+
@grid.get_cell(6, 7).set_alive
|
69
|
+
@grid.get_cell(7, 7).set_alive
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
data/lib/gol.rb
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
require_relative 'game'
|
3
|
+
|
4
|
+
module Gol
|
5
|
+
class Starter
|
6
|
+
|
7
|
+
attr_accessor :options
|
8
|
+
def initialize
|
9
|
+
@objects = [:glider] # TODO: more to come
|
10
|
+
@options = {}
|
11
|
+
end
|
12
|
+
|
13
|
+
def parse_options
|
14
|
+
optparse = OptionParser.new do |opts|
|
15
|
+
opts.banner = "Usage: gol [pause] [object] [size] [generations]"
|
16
|
+
|
17
|
+
@options[:pause] = 0.5
|
18
|
+
opts.on('-p', '--pause PAUSE', "Sets the sleep time in seconds each step
|
19
|
+
will take after printing out the game.
|
20
|
+
Default are 0.5 seconds.") do |time|
|
21
|
+
@options[:pause] = time.to_f
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
@options[:object] = nil
|
26
|
+
opts.on('-o', '--object OBJECT', "Sets a starting object to begin with.
|
27
|
+
It will appear on the Screen with no
|
28
|
+
additional living cells. Options are:
|
29
|
+
glider"
|
30
|
+
) do |ob|
|
31
|
+
@options[:object] = ob.to_sym
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
@options[:size] = 10
|
36
|
+
opts.on('-s', '--size SIZE', "Sets the size of the quadratic grid.
|
37
|
+
Default is a 10x10 grid."
|
38
|
+
) do |s|
|
39
|
+
@options[:size] = s.to_i
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
@options[:generations] = 10
|
44
|
+
opts.on('-g', '--generations GENERATIONS', "Sets the number of generations to
|
45
|
+
play with. Default are 10 generations."
|
46
|
+
) do |g|
|
47
|
+
@options[:generations] = g.to_i
|
48
|
+
end
|
49
|
+
|
50
|
+
opts.on('-h', '--help', 'Print this help screen') do
|
51
|
+
puts opts
|
52
|
+
exit
|
53
|
+
end
|
54
|
+
end # end of option parsing
|
55
|
+
|
56
|
+
optparse.parse!
|
57
|
+
|
58
|
+
end # end parse options
|
59
|
+
|
60
|
+
|
61
|
+
def main_script
|
62
|
+
parse_options
|
63
|
+
g = Game.new(@options[:size], @options[:pause])
|
64
|
+
if @options[:object].eql? :glider
|
65
|
+
g.glider
|
66
|
+
else
|
67
|
+
g.turn_alive_random_cells
|
68
|
+
end
|
69
|
+
@options[:generations].times do
|
70
|
+
g.step
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
s = Gol::Starter.new
|
78
|
+
s.main_script
|
data/lib/grid.rb
ADDED
@@ -0,0 +1,159 @@
|
|
1
|
+
require_relative 'cell'
|
2
|
+
|
3
|
+
module Gol
|
4
|
+
class Grid
|
5
|
+
attr_accessor :cells, :size
|
6
|
+
|
7
|
+
def initialize(size)
|
8
|
+
@size = size
|
9
|
+
@cells = Array.new
|
10
|
+
# gives us something like [[1, 1], [1, 2], [1, 3], ...]
|
11
|
+
coordinates = (1..size).to_a.product((1..size).to_a)
|
12
|
+
coordinates.each do |co|
|
13
|
+
c = Cell.new
|
14
|
+
# we want the rows first, better for printing
|
15
|
+
c.x = co[1]
|
16
|
+
c.y = co[0]
|
17
|
+
@cells << c
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def each
|
22
|
+
@cells.each do |c|
|
23
|
+
yield c
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def get_cell(x, y)
|
28
|
+
correct_cell = []
|
29
|
+
@cells.select do |cell|
|
30
|
+
correct_cell << cell if (cell.x == x and cell.y == y)
|
31
|
+
end
|
32
|
+
correct_cell.first
|
33
|
+
end
|
34
|
+
|
35
|
+
def get_neighbours(cell)
|
36
|
+
x = cell.x
|
37
|
+
y = cell.y
|
38
|
+
neighbours = []
|
39
|
+
neighbours << get_cell_left_above(x, y)
|
40
|
+
neighbours << get_cell_above(x, y)
|
41
|
+
neighbours << get_cell_right_above(x, y)
|
42
|
+
neighbours << get_left_cell(x, y)
|
43
|
+
neighbours << get_right_cell(x, y)
|
44
|
+
neighbours << get_cell_left_below(x, y)
|
45
|
+
neighbours << get_cell_below(x, y)
|
46
|
+
neighbours << get_cell_right_below(x, y)
|
47
|
+
end
|
48
|
+
|
49
|
+
def count_living_neighbours(cell)
|
50
|
+
neighbours = get_neighbours(cell)
|
51
|
+
count = 0
|
52
|
+
neighbours.each do |cell|
|
53
|
+
count += 1 if cell.alive?
|
54
|
+
end
|
55
|
+
count
|
56
|
+
end
|
57
|
+
|
58
|
+
def check_survival(cell)
|
59
|
+
c = count_living_neighbours(cell)
|
60
|
+
if !cell.alive? and c == 3
|
61
|
+
cell.will_live = true
|
62
|
+
elsif cell.alive? and c < 2
|
63
|
+
cell.will_live = false
|
64
|
+
elsif cell.alive? and (c == 2 or c == 3)
|
65
|
+
cell.will_live = true
|
66
|
+
elsif cell.alive? and c > 3
|
67
|
+
cell.will_live = false
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
|
73
|
+
def get_cell_above(x, y)
|
74
|
+
if y == 1
|
75
|
+
get_cell(x, @size)
|
76
|
+
else
|
77
|
+
get_cell(x, y - 1)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def get_cell_left_above(x, y)
|
82
|
+
if x == 1 and y == 1
|
83
|
+
get_cell(@size, @size)
|
84
|
+
elsif x == 1
|
85
|
+
get_cell(@size, y - 1)
|
86
|
+
elsif y == 1
|
87
|
+
get_cell(x - 1, @size)
|
88
|
+
else
|
89
|
+
get_cell(x - 1, y - 1)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def get_cell_right_above(x, y)
|
94
|
+
if x == @size and y == 1
|
95
|
+
get_cell(1, @size)
|
96
|
+
elsif y == 1
|
97
|
+
get_cell(x + 1, @size)
|
98
|
+
elsif x == @size
|
99
|
+
get_cell(1, y - 1)
|
100
|
+
else
|
101
|
+
get_cell(x + 1, y - 1)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
|
106
|
+
def get_left_cell(x, y)
|
107
|
+
if x == 1
|
108
|
+
get_cell(@size, y)
|
109
|
+
else
|
110
|
+
get_cell(x - 1, y)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def get_right_cell(x, y)
|
115
|
+
if x == @size
|
116
|
+
get_cell(1, y)
|
117
|
+
else
|
118
|
+
get_cell(x + 1, y)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
|
123
|
+
def get_cell_left_below(x, y)
|
124
|
+
if x == 1 and y == @size
|
125
|
+
get_cell(@size, 1)
|
126
|
+
elsif x == 1
|
127
|
+
get_cell(@size, y + 1)
|
128
|
+
elsif y == @size
|
129
|
+
get_cell(x - 1, 1)
|
130
|
+
else
|
131
|
+
get_cell(x - 1, y + 1)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
|
136
|
+
def get_cell_below(x, y)
|
137
|
+
if y == @size
|
138
|
+
get_cell(x, 1)
|
139
|
+
else
|
140
|
+
get_cell(x, y + 1)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
|
145
|
+
def get_cell_right_below(x, y)
|
146
|
+
if x == @size and y == @size
|
147
|
+
get_cell(1, 1)
|
148
|
+
elsif y == @size
|
149
|
+
get_cell(x + 1, 1)
|
150
|
+
elsif x == @size
|
151
|
+
get_cell(1, y + 1)
|
152
|
+
else
|
153
|
+
get_cell(x + 1, y + 1)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
|
158
|
+
end
|
159
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require_relative '../cell'
|
2
|
+
|
3
|
+
describe Gol::Cell do
|
4
|
+
let(:cell) { Gol::Cell.new }
|
5
|
+
|
6
|
+
it "should know if its alive" do
|
7
|
+
(cell.respond_to? :alive?).should be true
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should be killable" do
|
11
|
+
(cell.respond_to? :kill).should be true
|
12
|
+
end
|
13
|
+
|
14
|
+
it "has a x-coordinate" do
|
15
|
+
(cell.respond_to? :x).should be true
|
16
|
+
end
|
17
|
+
|
18
|
+
it "has a y-coordinate" do
|
19
|
+
(cell.respond_to? :y).should be true
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should know wheter it will live in the next generation" do
|
23
|
+
(cell.respond_to? :will_live).should be true
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should be able to be turned alive" do
|
27
|
+
(cell.respond_to? :set_alive).should be true
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should be dead after creation" do
|
31
|
+
cell.alive?.should be false
|
32
|
+
end
|
33
|
+
|
34
|
+
it "shouldn't be marked as survivor on creation" do
|
35
|
+
cell.will_live?.should be false
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should be alive after turned alive" do
|
39
|
+
cell.alive?.should be false
|
40
|
+
cell.set_alive
|
41
|
+
cell.alive?.should be true
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should be dead after killing" do
|
45
|
+
cell.alive?.should be false
|
46
|
+
cell.set_alive
|
47
|
+
cell.alive?.should be true
|
48
|
+
cell.kill
|
49
|
+
cell.alive?.should be false
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require_relative '../game'
|
2
|
+
|
3
|
+
describe Gol::Game do
|
4
|
+
let(:game) { Gol::Game.new(5, 1) }
|
5
|
+
it "has a grid" do
|
6
|
+
(game.respond_to? :grid).should be true
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should have a print method" do
|
10
|
+
(game.respond_to? :print_game).should be true
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
it "should be able to turn random cells alive" do
|
15
|
+
(game.respond_to? :turn_alive_random_cells).should be true
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
it "should be able to produce a glider" do
|
20
|
+
(game.respond_to? :glider).should be true
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
it "should be able to perform a step and apply the rules" do
|
25
|
+
(game.respond_to? :step).should be true
|
26
|
+
game.grid.get_cell(2, 2).alive = true
|
27
|
+
game.step
|
28
|
+
game.grid.get_cell(2, 2).alive?.should be false
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
end
|
@@ -0,0 +1,399 @@
|
|
1
|
+
require_relative '../grid'
|
2
|
+
|
3
|
+
describe Gol::Grid do
|
4
|
+
let(:grid) { Gol::Grid.new(5) }
|
5
|
+
|
6
|
+
it "has cells" do
|
7
|
+
(grid.respond_to? :cells).should be true
|
8
|
+
end
|
9
|
+
|
10
|
+
|
11
|
+
its "cells should be an Array" do
|
12
|
+
grid.cells.class.should be Array
|
13
|
+
end
|
14
|
+
|
15
|
+
its "number of cells should be size x size" do
|
16
|
+
grid.cells.size.should be 25
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should be able to yield cells" do
|
20
|
+
(grid.respond_to? :each).should be true
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should be able to return a specific cell" do
|
24
|
+
(grid.respond_to? :get_cell).should be true
|
25
|
+
cell = grid.get_cell(2, 2)
|
26
|
+
cell.x.should be 2
|
27
|
+
cell.y.should be 2
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should be able to return the cell above a cell" do
|
31
|
+
(grid.respond_to? :get_cell_above).should be true
|
32
|
+
cell = grid.get_cell_above(2, 2)
|
33
|
+
cell.x.should be 2
|
34
|
+
cell.y.should be 1
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should be able to return the cell above a cell in an unlimited grid" do
|
38
|
+
cell = grid.get_cell_above(3, 1)
|
39
|
+
cell.x.should be 3
|
40
|
+
cell.y.should be 5
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should be able to return the cell left above a cell" do
|
44
|
+
(grid.respond_to? :get_cell_left_above).should be true
|
45
|
+
cell = grid.get_cell_left_above(2, 2)
|
46
|
+
cell.x.should be 1
|
47
|
+
cell.y.should be 1
|
48
|
+
|
49
|
+
cell = grid.get_cell_left_above(5, 5)
|
50
|
+
cell.x.should be 4
|
51
|
+
cell.y.should be 4
|
52
|
+
|
53
|
+
cell = grid.get_cell_left_above(2, 4)
|
54
|
+
cell.x.should be 1
|
55
|
+
cell.y.should be 3
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
it "should be able to return the cell left above a cell on an unlimited grid" do
|
60
|
+
cell = grid.get_cell_left_above(1, 1)
|
61
|
+
cell.x.should be 5
|
62
|
+
cell.y.should be 5
|
63
|
+
cell = grid.get_cell_left_above(2, 1)
|
64
|
+
cell.x.should be 1
|
65
|
+
cell.y.should be 5
|
66
|
+
cell = grid.get_cell_left_above(3, 1)
|
67
|
+
cell.x.should be 2
|
68
|
+
cell.y.should be 5
|
69
|
+
cell = grid.get_cell_left_above(4, 1)
|
70
|
+
cell.x.should be 3
|
71
|
+
cell.y.should be 5
|
72
|
+
cell = grid.get_cell_left_above(5, 1)
|
73
|
+
cell.x.should be 4
|
74
|
+
cell.y.should be 5
|
75
|
+
|
76
|
+
cell = grid.get_cell_left_above(1, 2)
|
77
|
+
cell.x.should be 5
|
78
|
+
cell.y.should be 1
|
79
|
+
cell = grid.get_cell_left_above(1, 3)
|
80
|
+
cell.x.should be 5
|
81
|
+
cell.y.should be 2
|
82
|
+
cell = grid.get_cell_left_above(1, 4)
|
83
|
+
cell.x.should be 5
|
84
|
+
cell.y.should be 3
|
85
|
+
cell = grid.get_cell_left_above(1, 5)
|
86
|
+
cell.x.should be 5
|
87
|
+
cell.y.should be 4
|
88
|
+
end
|
89
|
+
|
90
|
+
|
91
|
+
it "should be able to return the cell right above a cell" do
|
92
|
+
(grid.respond_to? :get_cell_right_above).should be true
|
93
|
+
cell = grid.get_cell_right_above(2, 2)
|
94
|
+
cell.x.should be 3
|
95
|
+
cell.y.should be 1
|
96
|
+
|
97
|
+
cell = grid.get_cell_right_above(4, 4)
|
98
|
+
cell.x.should be 5
|
99
|
+
cell.y.should be 3
|
100
|
+
|
101
|
+
cell = grid.get_cell_right_above(2, 4)
|
102
|
+
cell.x.should be 3
|
103
|
+
cell.y.should be 3
|
104
|
+
end
|
105
|
+
|
106
|
+
|
107
|
+
|
108
|
+
it "should be able to return the cell left above a cell on an unlimited grid" do
|
109
|
+
cell = grid.get_cell_right_above(5, 1)
|
110
|
+
cell.x.should be 1
|
111
|
+
cell.y.should be 5
|
112
|
+
cell = grid.get_cell_right_above(4, 1)
|
113
|
+
cell.x.should be 5
|
114
|
+
cell.y.should be 5
|
115
|
+
cell = grid.get_cell_right_above(3, 1)
|
116
|
+
cell.x.should be 4
|
117
|
+
cell.y.should be 5
|
118
|
+
cell = grid.get_cell_right_above(2, 1)
|
119
|
+
cell.x.should be 3
|
120
|
+
cell.y.should be 5
|
121
|
+
cell = grid.get_cell_right_above(1, 1)
|
122
|
+
cell.x.should be 2
|
123
|
+
cell.y.should be 5
|
124
|
+
|
125
|
+
cell = grid.get_cell_right_above(5, 2)
|
126
|
+
cell.x.should be 1
|
127
|
+
cell.y.should be 1
|
128
|
+
cell = grid.get_cell_right_above(5, 3)
|
129
|
+
cell.x.should be 1
|
130
|
+
cell.y.should be 2
|
131
|
+
cell = grid.get_cell_right_above(5, 4)
|
132
|
+
cell.x.should be 1
|
133
|
+
cell.y.should be 3
|
134
|
+
cell = grid.get_cell_right_above(5, 5)
|
135
|
+
cell.x.should be 1
|
136
|
+
cell.y.should be 4
|
137
|
+
end
|
138
|
+
|
139
|
+
|
140
|
+
it "should be able to return the cell left of a cell" do
|
141
|
+
(grid.respond_to? :get_left_cell).should be true
|
142
|
+
cell = grid.get_left_cell(2, 2)
|
143
|
+
cell.x.should be 1
|
144
|
+
cell.y.should be 2
|
145
|
+
end
|
146
|
+
|
147
|
+
it "should be able to return the cell left of a cell in an unlimited grid" do
|
148
|
+
cell = grid.get_left_cell(1, 4)
|
149
|
+
cell.x.should be 5
|
150
|
+
cell.y.should be 4
|
151
|
+
end
|
152
|
+
|
153
|
+
|
154
|
+
it "should be able to return the cell right of a cell" do
|
155
|
+
(grid.respond_to? :get_right_cell).should be true
|
156
|
+
cell = grid.get_right_cell(2, 2)
|
157
|
+
cell.x.should be 3
|
158
|
+
cell.y.should be 2
|
159
|
+
end
|
160
|
+
|
161
|
+
it "should be able to return the cell right of a cell in an unlimited grid" do
|
162
|
+
cell = grid.get_right_cell(5, 2)
|
163
|
+
cell.x.should be 1
|
164
|
+
cell.y.should be 2
|
165
|
+
end
|
166
|
+
|
167
|
+
|
168
|
+
it "should be able to return the cell left below a cell" do
|
169
|
+
(grid.respond_to? :get_cell_left_below).should be true
|
170
|
+
cell = grid.get_cell_left_below(2, 2)
|
171
|
+
cell.x.should be 1
|
172
|
+
cell.y.should be 3
|
173
|
+
|
174
|
+
cell = grid.get_cell_left_below(4, 4)
|
175
|
+
cell.x.should be 3
|
176
|
+
cell.y.should be 5
|
177
|
+
|
178
|
+
cell = grid.get_cell_left_below(2, 4)
|
179
|
+
cell.x.should be 1
|
180
|
+
cell.y.should be 5
|
181
|
+
end
|
182
|
+
|
183
|
+
it "should be able to return the cell left below a cell on an unlimited grid" do
|
184
|
+
cell = grid.get_cell_left_below(1, 5)
|
185
|
+
cell.x.should be 5
|
186
|
+
cell.y.should be 1
|
187
|
+
cell = grid.get_cell_left_below(1, 4)
|
188
|
+
cell.x.should be 5
|
189
|
+
cell.y.should be 5
|
190
|
+
cell = grid.get_cell_left_below(1, 3)
|
191
|
+
cell.x.should be 5
|
192
|
+
cell.y.should be 4
|
193
|
+
cell = grid.get_cell_left_below(1, 2)
|
194
|
+
cell.x.should be 5
|
195
|
+
cell.y.should be 3
|
196
|
+
cell = grid.get_cell_left_below(1, 1)
|
197
|
+
cell.x.should be 5
|
198
|
+
cell.y.should be 2
|
199
|
+
|
200
|
+
cell = grid.get_cell_left_below(2, 5)
|
201
|
+
cell.x.should be 1
|
202
|
+
cell.y.should be 1
|
203
|
+
cell = grid.get_cell_left_below(3, 5)
|
204
|
+
cell.x.should be 2
|
205
|
+
cell.y.should be 1
|
206
|
+
cell = grid.get_cell_left_below(4, 5)
|
207
|
+
cell.x.should be 3
|
208
|
+
cell.y.should be 1
|
209
|
+
cell = grid.get_cell_left_below(5, 5)
|
210
|
+
cell.x.should be 4
|
211
|
+
cell.y.should be 1
|
212
|
+
end
|
213
|
+
|
214
|
+
|
215
|
+
it "should be able to return the cell below a cell" do
|
216
|
+
(grid.respond_to? :get_cell_below).should be true
|
217
|
+
cell = grid.get_cell_below(2, 2)
|
218
|
+
cell.x.should be 2
|
219
|
+
cell.y.should be 3
|
220
|
+
end
|
221
|
+
|
222
|
+
it "should be able to return the cell below a cell in an unlimited grid" do
|
223
|
+
cell = grid.get_cell_below(3, 5)
|
224
|
+
cell.x.should be 3
|
225
|
+
cell.y.should be 1
|
226
|
+
end
|
227
|
+
|
228
|
+
|
229
|
+
it "should be able to return the cell right below a cell" do
|
230
|
+
(grid.respond_to? :get_cell_right_below).should be true
|
231
|
+
cell = grid.get_cell_right_below(2, 2)
|
232
|
+
cell.x.should be 3
|
233
|
+
cell.y.should be 3
|
234
|
+
|
235
|
+
cell = grid.get_cell_right_below(4, 4)
|
236
|
+
cell.x.should be 5
|
237
|
+
cell.y.should be 5
|
238
|
+
|
239
|
+
cell = grid.get_cell_right_below(2, 4)
|
240
|
+
cell.x.should be 3
|
241
|
+
cell.y.should be 5
|
242
|
+
end
|
243
|
+
|
244
|
+
it "should be able to return the cell right below a cell on an unlimited grid" do
|
245
|
+
cell = grid.get_cell_right_below(5, 5)
|
246
|
+
cell.x.should be 1
|
247
|
+
cell.y.should be 1
|
248
|
+
cell = grid.get_cell_right_below(4, 5)
|
249
|
+
cell.x.should be 5
|
250
|
+
cell.y.should be 1
|
251
|
+
cell = grid.get_cell_right_below(3, 5)
|
252
|
+
cell.x.should be 4
|
253
|
+
cell.y.should be 1
|
254
|
+
cell = grid.get_cell_right_below(2, 5)
|
255
|
+
cell.x.should be 3
|
256
|
+
cell.y.should be 1
|
257
|
+
cell = grid.get_cell_right_below(1, 5)
|
258
|
+
cell.x.should be 2
|
259
|
+
cell.y.should be 1
|
260
|
+
|
261
|
+
cell = grid.get_cell_right_below(5, 4)
|
262
|
+
cell.x.should be 1
|
263
|
+
cell.y.should be 5
|
264
|
+
cell = grid.get_cell_right_below(5, 3)
|
265
|
+
cell.x.should be 1
|
266
|
+
cell.y.should be 4
|
267
|
+
cell = grid.get_cell_right_below(5, 2)
|
268
|
+
cell.x.should be 1
|
269
|
+
cell.y.should be 3
|
270
|
+
cell = grid.get_cell_right_below(5, 1)
|
271
|
+
cell.x.should be 1
|
272
|
+
cell.y.should be 2
|
273
|
+
end
|
274
|
+
|
275
|
+
it "should be able to get all neighbours of a cell" do
|
276
|
+
(grid.respond_to? :get_neighbours).should be true
|
277
|
+
cell = grid.get_cell(2, 2)
|
278
|
+
neighbours = grid.get_neighbours(cell)
|
279
|
+
neighbours.size.should be 8
|
280
|
+
neighbours.first.x.should be 1
|
281
|
+
neighbours.first.y.should be 1
|
282
|
+
|
283
|
+
neighbours[1].x.should be 2
|
284
|
+
neighbours[1].y.should be 1
|
285
|
+
|
286
|
+
neighbours[2].x.should be 3
|
287
|
+
neighbours[2].y.should be 1
|
288
|
+
|
289
|
+
neighbours[3].x.should be 1
|
290
|
+
neighbours[3].y.should be 2
|
291
|
+
|
292
|
+
neighbours[4].x.should be 3
|
293
|
+
neighbours[4].y.should be 2
|
294
|
+
|
295
|
+
neighbours[5].x.should be 1
|
296
|
+
neighbours[5].y.should be 3
|
297
|
+
|
298
|
+
neighbours[6].x.should be 2
|
299
|
+
neighbours[6].y.should be 3
|
300
|
+
|
301
|
+
neighbours[7].x.should be 3
|
302
|
+
neighbours[7].y.should be 3
|
303
|
+
end
|
304
|
+
|
305
|
+
|
306
|
+
it "should be able to get all neighbours of a cell on an unlimited grid" do
|
307
|
+
cell = grid.get_cell(5, 5)
|
308
|
+
neighbours = grid.get_neighbours(cell)
|
309
|
+
neighbours.size.should be 8
|
310
|
+
# upper left
|
311
|
+
neighbours.first.x.should be 4
|
312
|
+
neighbours.first.y.should be 4
|
313
|
+
|
314
|
+
# upper
|
315
|
+
neighbours[1].x.should be 5
|
316
|
+
neighbours[1].y.should be 4
|
317
|
+
|
318
|
+
# upper right
|
319
|
+
neighbours[2].x.should be 1
|
320
|
+
neighbours[2].y.should be 4
|
321
|
+
|
322
|
+
# left
|
323
|
+
neighbours[3].x.should be 4
|
324
|
+
neighbours[3].y.should be 5
|
325
|
+
|
326
|
+
# right
|
327
|
+
neighbours[4].x.should be 1
|
328
|
+
neighbours[4].y.should be 5
|
329
|
+
|
330
|
+
# lower left
|
331
|
+
neighbours[5].x.should be 4
|
332
|
+
neighbours[5].y.should be 1
|
333
|
+
|
334
|
+
# below
|
335
|
+
neighbours[6].x.should be 5
|
336
|
+
neighbours[6].y.should be 1
|
337
|
+
|
338
|
+
# lower right
|
339
|
+
neighbours[7].x.should be 1
|
340
|
+
neighbours[7].y.should be 1
|
341
|
+
end
|
342
|
+
|
343
|
+
it "should be able to count living neighbours of a cell" do
|
344
|
+
(grid.respond_to? :count_living_neighbours).should be true
|
345
|
+
cell = grid.get_cell(2, 2)
|
346
|
+
grid.get_cell(1, 1).alive = true
|
347
|
+
grid.get_cell(2, 1).alive = true
|
348
|
+
grid.get_cell(3, 3).alive = true
|
349
|
+
grid.count_living_neighbours(cell).should be 3
|
350
|
+
end
|
351
|
+
|
352
|
+
it "should be able to check whether a cell will survive" do
|
353
|
+
(grid.respond_to? :check_survival).should be true
|
354
|
+
end
|
355
|
+
|
356
|
+
it "should apply rule one (3 living neighbours == will be alive)" do
|
357
|
+
cell = grid.get_cell(2, 2)
|
358
|
+
grid.get_cell(1, 1).alive = true
|
359
|
+
grid.get_cell(2, 1).alive = true
|
360
|
+
grid.get_cell(3, 3).alive = true
|
361
|
+
grid.check_survival(cell)
|
362
|
+
cell.will_live?.should be true
|
363
|
+
end
|
364
|
+
|
365
|
+
it "should apply rule two (less than 2 living neighbours == will die)" do
|
366
|
+
cell = grid.get_cell(2, 2)
|
367
|
+
cell.alive = true
|
368
|
+
grid.get_cell(1, 1).alive = true
|
369
|
+
grid.check_survival(cell)
|
370
|
+
cell.will_live?.should be false
|
371
|
+
end
|
372
|
+
|
373
|
+
it "should apply rule three (2 or 3 living neighbours == will live)" do
|
374
|
+
cell = grid.get_cell(2, 2)
|
375
|
+
cell.alive = true
|
376
|
+
grid.get_cell(1, 1).alive = true
|
377
|
+
grid.get_cell(2, 1).alive = true
|
378
|
+
grid.check_survival(cell)
|
379
|
+
cell.will_live?.should be true
|
380
|
+
|
381
|
+
grid.get_cell(3, 3).alive = true
|
382
|
+
grid.check_survival(cell)
|
383
|
+
cell.will_live?.should be true
|
384
|
+
end
|
385
|
+
|
386
|
+
it "should apply rule four (more than 3 neighbours == will die)" do
|
387
|
+
cell = grid.get_cell(2, 2)
|
388
|
+
grid.get_cell(1, 1).alive = true
|
389
|
+
grid.get_cell(2, 1).alive = true
|
390
|
+
grid.get_cell(3, 3).alive = true
|
391
|
+
grid.get_cell(1, 2).alive = true
|
392
|
+
grid.check_survival(cell)
|
393
|
+
cell.will_live?.should be false
|
394
|
+
end
|
395
|
+
|
396
|
+
|
397
|
+
|
398
|
+
|
399
|
+
end
|
metadata
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: gol
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '0.2'
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Alexander Huber
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-08-03 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: gol lets one start random games of Game of Life with choosebale params
|
15
|
+
like grid size, speed, duration and objects.
|
16
|
+
email: alih83@gmx.de
|
17
|
+
executables:
|
18
|
+
- gol
|
19
|
+
extensions: []
|
20
|
+
extra_rdoc_files: []
|
21
|
+
files:
|
22
|
+
- lib/spec/cell_spec.rb
|
23
|
+
- lib/spec/game_spec.rb
|
24
|
+
- lib/spec/grid_spec.rb
|
25
|
+
- lib/game.rb
|
26
|
+
- lib/cell.rb
|
27
|
+
- lib/grid.rb
|
28
|
+
- lib/gol.rb
|
29
|
+
- bin/gol
|
30
|
+
homepage: https://github.com/alihuber
|
31
|
+
licenses: []
|
32
|
+
post_install_message:
|
33
|
+
rdoc_options: []
|
34
|
+
require_paths:
|
35
|
+
- lib
|
36
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
37
|
+
none: false
|
38
|
+
requirements:
|
39
|
+
- - ! '>='
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
42
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
43
|
+
none: false
|
44
|
+
requirements:
|
45
|
+
- - ! '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
requirements: []
|
49
|
+
rubyforge_project:
|
50
|
+
rubygems_version: 1.8.24
|
51
|
+
signing_key:
|
52
|
+
specification_version: 3
|
53
|
+
summary: An implementation of Conway's Game of Life
|
54
|
+
test_files: []
|