cellular_automata 0.1.2 → 0.1.4
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 +4 -4
- data/.gitignore +1 -0
- data/Rakefile +3 -0
- data/bin/cell_console +17 -0
- data/bin/cell_gif +52 -0
- data/cellular_automata.gemspec +13 -10
- data/ext/cellular_c/cellular_c.c +76 -0
- data/ext/cellular_c/extconf.rb +6 -0
- data/lib/cellular_automata/board.rb +32 -27
- data/lib/cellular_automata/gif_writer.rb +56 -0
- data/lib/cellular_automata/gui_window.rb +12 -3
- data/lib/cellular_automata/rule.rb +12 -15
- data/lib/cellular_automata/version.rb +1 -1
- data/lib/cellular_automata.rb +3 -0
- metadata +44 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0237b3c22f9d23179fc50a5c88bc5217ce95025e
|
4
|
+
data.tar.gz: 93bcb9d782c3ec0643fdee8b9e04d0de01c62a3c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b0ae054a68622f16753da6ca3968a20c64af2ea6af76a342a5223f10f435553cc71be98315f607b92f159cf7e29eb435411253f5a626dc13e96d9ba8855ab8f9
|
7
|
+
data.tar.gz: dc06e35c815e74eeed6ba5048f352410937d8b51e67d827d7f7b3112c83cc087d3196f5910e357900fd61693d1f9227734cb316652be05de7c3fabe0f976acd7
|
data/.gitignore
CHANGED
data/Rakefile
CHANGED
data/bin/cell_console
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'cellular_automata'
|
4
|
+
require 'optparse'
|
5
|
+
require 'byebug'
|
6
|
+
require 'pry'
|
7
|
+
|
8
|
+
width = 120
|
9
|
+
height = 30
|
10
|
+
rule = 'B3S2'
|
11
|
+
board = CellularAutomata::Board.new(width: width, height: height, rule: rule)
|
12
|
+
board.tick!
|
13
|
+
board.tick!
|
14
|
+
puts board.to_s
|
15
|
+
state = board.state
|
16
|
+
binding.pry
|
17
|
+
exit
|
data/bin/cell_gif
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'cellular_automata'
|
4
|
+
require 'optparse'
|
5
|
+
require 'gosu'
|
6
|
+
|
7
|
+
def opts_from_cli
|
8
|
+
options = {}
|
9
|
+
opt_parser = OptionParser.new do |opts|
|
10
|
+
opts.program_name = File.basename(__FILE__)
|
11
|
+
opts.banner = "#{opts.program_name} [options] RULE"
|
12
|
+
opts.on('-w WIDTH', '--width WIDTH', 'Set width') { |w| options[:width] = w.to_i }
|
13
|
+
opts.on('-h HEIGHT', '--height HEIGHT', 'Set height') { |h| options[:height] = h.to_i }
|
14
|
+
opts.on('-s SCALE', '--scale SCALE', 'Factor by which to scale game board') { |s| options[:scale] = s.to_i }
|
15
|
+
opts.on('-c WIDTH', '--cell-width WIDTH', 'Factor by which to scale cells', 'Use 1 for an \'LED\' look',
|
16
|
+
'Use 2 for no borders around cells', 'or choose anything in between') {|w| options[:cell_scale] = w.to_f }
|
17
|
+
opts.on('-f FRAMES', '--frames FRAMES', 'Number of frames to write') { |f| options[:frames] = f.to_i }
|
18
|
+
opts.on('-v', '--version', 'Print version information') do
|
19
|
+
puts "#{File.basename(__FILE__)} #{CellularAutomata::VERSION}"
|
20
|
+
exit true
|
21
|
+
end
|
22
|
+
opts.on('--help', 'Display this screen') do
|
23
|
+
puts opts
|
24
|
+
exit true
|
25
|
+
end
|
26
|
+
end
|
27
|
+
begin
|
28
|
+
opt_parser.parse!
|
29
|
+
rescue OptionParser::InvalidOption => e
|
30
|
+
puts e.message
|
31
|
+
exit false
|
32
|
+
end
|
33
|
+
options
|
34
|
+
end
|
35
|
+
|
36
|
+
opts = opts_from_cli
|
37
|
+
opts[:width] ||= 160
|
38
|
+
opts[:height] ||= 120
|
39
|
+
opts[:scale] ||= 1
|
40
|
+
opts[:cell_scale] ||= 2.0
|
41
|
+
opts[:cell_scale] = 2.0 if opts[:cell_scale] > 2.0
|
42
|
+
opts[:cell_scale] = 1.0 if opts[:cell_scale] < 1.0
|
43
|
+
opts[:frames] ||= 100
|
44
|
+
rule = ARGV[0] || 'B3S2'
|
45
|
+
opts[:rule] = rule
|
46
|
+
|
47
|
+
trap 'SIGINT' do
|
48
|
+
exit
|
49
|
+
end
|
50
|
+
|
51
|
+
CellularAutomata::GifWriter.write(opts)
|
52
|
+
exit
|
data/cellular_automata.gemspec
CHANGED
@@ -4,26 +4,29 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
require 'cellular_automata/version'
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
7
|
+
spec.name = "cellular_automata"
|
8
8
|
spec.version = CellularAutomata::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
9
|
+
spec.authors = ["Forrest Fleming"]
|
10
|
+
spec.email = ["ffleming@gmail.com"]
|
11
11
|
|
12
12
|
spec.summary = %q{A simulation of cellular automata}
|
13
13
|
spec.description = %q{A set of 0-player games, of which Conway's Game of Life is a member.}
|
14
|
-
spec.homepage =
|
14
|
+
spec.homepage = "https://github.com/ffleming/cellular_automata"
|
15
15
|
|
16
16
|
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
17
|
-
spec.bindir =
|
17
|
+
spec.bindir = "bin"
|
18
18
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
19
|
-
spec.require_paths = [
|
19
|
+
spec.require_paths = ["lib"]
|
20
20
|
|
21
21
|
spec.license = 'MIT'
|
22
22
|
|
23
|
-
spec.
|
24
|
-
|
25
|
-
spec.
|
26
|
-
spec.
|
23
|
+
spec.extensions << 'ext/cellular_c/extconf.rb'
|
24
|
+
|
25
|
+
spec.add_runtime_dependency "gosu", '~> 0', '>= 0.9'
|
26
|
+
spec.add_runtime_dependency "rmagick", '~> 2', '>= 2.15'
|
27
|
+
spec.add_development_dependency "bundler", "~> 1", ">= 1.8"
|
28
|
+
spec.add_development_dependency "rake-compiler", '~> 0', '>= 0.9'
|
29
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
27
30
|
spec.add_development_dependency 'pry', '~> 0.10'
|
28
31
|
spec.add_development_dependency 'byebug', '~> 4'
|
29
32
|
spec.add_development_dependency 'pry-byebug', '~> 3.1'
|
@@ -0,0 +1,76 @@
|
|
1
|
+
#include <ruby.h>
|
2
|
+
#include <stdio.h>
|
3
|
+
|
4
|
+
VALUE CellularC = Qnil;
|
5
|
+
void Init_cellular_c();
|
6
|
+
int cell_value(VALUE, int);
|
7
|
+
int neighbor_population_of(VALUE, int, int);
|
8
|
+
VALUE method_dup_state(VALUE, VALUE);
|
9
|
+
VALUE method_next_state(VALUE, VALUE, VALUE);
|
10
|
+
|
11
|
+
void Init_cellular_c() {
|
12
|
+
CellularC = rb_define_module("CellularC");
|
13
|
+
rb_define_singleton_method(CellularC, "dup_state", method_dup_state, 1);
|
14
|
+
rb_define_singleton_method(CellularC, "next_state", method_next_state, 2);
|
15
|
+
}
|
16
|
+
|
17
|
+
int cell_value(VALUE rule, int num_neighbors) {
|
18
|
+
VALUE rule_array = rb_iv_get(rule, "@rule_array");
|
19
|
+
VALUE result = rb_ary_entry(rule_array, num_neighbors);
|
20
|
+
VALUE live = ID2SYM(rb_intern("birth"));
|
21
|
+
VALUE die = ID2SYM(rb_intern("die"));
|
22
|
+
if(result == die) {
|
23
|
+
return 0;
|
24
|
+
} else if(result == live) {
|
25
|
+
return 1;
|
26
|
+
}
|
27
|
+
return -1;
|
28
|
+
}
|
29
|
+
|
30
|
+
int neighbor_population_of(VALUE state, int x, int y) {
|
31
|
+
int height = (int)RARRAY_LEN(state);
|
32
|
+
int width = (int)RARRAY_LEN(rb_ary_entry(state, 0));
|
33
|
+
int min_x = x > 1 ? x - 1 : 0;
|
34
|
+
int max_x = x < width - 2 ? x + 1 : width - 1;
|
35
|
+
int min_y = y > 1 ? y - 1 : 0;
|
36
|
+
int max_y = y < height - 2 ? y + 1 : height - 1;
|
37
|
+
int ret = 0;
|
38
|
+
|
39
|
+
for(int row = min_y; row <= max_y; row++) {
|
40
|
+
VALUE row_array = rb_ary_entry(state, row);
|
41
|
+
for(int col = min_x; col <= max_x; col++) {
|
42
|
+
int alive = FIX2INT(rb_ary_entry(row_array, col));
|
43
|
+
if((alive == 1) && ((x != col) || (y != row))) {
|
44
|
+
ret += 1;
|
45
|
+
}
|
46
|
+
}
|
47
|
+
}
|
48
|
+
return ret;
|
49
|
+
}
|
50
|
+
|
51
|
+
VALUE method_next_state(VALUE self, VALUE state, VALUE rule) {
|
52
|
+
VALUE next_state = method_dup_state(self, state);
|
53
|
+
int height = (int)RARRAY_LEN(state);
|
54
|
+
int width = (int)RARRAY_LEN(rb_ary_entry(state, 0));
|
55
|
+
for(int row = 0; row < height; row++) {
|
56
|
+
VALUE row_array = rb_ary_entry(next_state, row);
|
57
|
+
for(int col = 0; col < width; col++) {
|
58
|
+
int new_value = cell_value(rule, neighbor_population_of(state, col, row));
|
59
|
+
if(new_value == -1) {
|
60
|
+
continue;
|
61
|
+
}
|
62
|
+
rb_ary_store(row_array, col, INT2FIX(new_value));
|
63
|
+
}
|
64
|
+
}
|
65
|
+
return next_state;
|
66
|
+
}
|
67
|
+
|
68
|
+
VALUE method_dup_state(VALUE self, VALUE state) {
|
69
|
+
int height = (int)RARRAY_LEN(state);
|
70
|
+
VALUE dup = rb_ary_new2(height);
|
71
|
+
for(int y = 0; y < height; y++) {
|
72
|
+
VALUE row = rb_ary_dup(rb_ary_entry(state, y));
|
73
|
+
rb_ary_push(dup, row);
|
74
|
+
}
|
75
|
+
return dup;
|
76
|
+
}
|
@@ -1,10 +1,13 @@
|
|
1
1
|
class CellularAutomata::Board
|
2
|
-
attr_reader :width, :height, :rule
|
3
|
-
def initialize(rule: 'B3S2', width: 80, height: 20)
|
2
|
+
attr_reader :width, :height, :rule, :history, :state
|
3
|
+
def initialize(rule: 'B3S2', width: 80, height: 20, max_history: 2)
|
4
4
|
@height = height
|
5
5
|
@width = width
|
6
6
|
@state = build_array
|
7
7
|
@rule = CellularAutomata::Rule.new(rule)
|
8
|
+
@history = []
|
9
|
+
@max_history = max_history
|
10
|
+
max_history.times { history.push build_array }
|
8
11
|
seed!
|
9
12
|
end
|
10
13
|
|
@@ -14,7 +17,7 @@ class CellularAutomata::Board
|
|
14
17
|
@state.each do |row|
|
15
18
|
ret << "|"
|
16
19
|
row.each do |cell|
|
17
|
-
ret << cell
|
20
|
+
ret << (cell == 0 ? ' ' : '*' )
|
18
21
|
end
|
19
22
|
ret << "|\n"
|
20
23
|
end
|
@@ -22,17 +25,24 @@ class CellularAutomata::Board
|
|
22
25
|
end
|
23
26
|
|
24
27
|
def tick!
|
25
|
-
next_state =
|
26
|
-
|
27
|
-
|
28
|
-
end
|
28
|
+
next_state = CellularC.next_state(@state, rule)
|
29
|
+
history.unshift CellularC.dup_state(@state)
|
30
|
+
history.pop if history.length > @max_history
|
29
31
|
@state = next_state
|
30
32
|
end
|
31
33
|
|
34
|
+
def kill(array: , x: , y: )
|
35
|
+
array[y][x] = 0
|
36
|
+
end
|
37
|
+
|
38
|
+
def live(array: , x: , y: )
|
39
|
+
array[y][x] = 1
|
40
|
+
end
|
41
|
+
|
32
42
|
def each_cell
|
33
43
|
(0..height-1).each do |y|
|
34
44
|
(0..width-1).each do |x|
|
35
|
-
yield
|
45
|
+
yield(x, y)
|
36
46
|
end
|
37
47
|
end
|
38
48
|
end
|
@@ -40,7 +50,7 @@ class CellularAutomata::Board
|
|
40
50
|
private
|
41
51
|
|
42
52
|
def seed!
|
43
|
-
each_cell { |
|
53
|
+
each_cell { |x, y| @state[y][x] = 1 if rand < 0.1 }
|
44
54
|
end
|
45
55
|
|
46
56
|
def build_array
|
@@ -48,29 +58,24 @@ class CellularAutomata::Board
|
|
48
58
|
(0..height-1).each do |y|
|
49
59
|
arr[y] = []
|
50
60
|
(0..width-1).each do |x|
|
51
|
-
arr[y][x] =
|
61
|
+
arr[y][x] = 0
|
52
62
|
end
|
53
63
|
end
|
54
64
|
return arr
|
55
65
|
end
|
56
66
|
|
57
|
-
def neighbor_population_of(
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
y = cell.y ; x = cell.x
|
70
|
-
[ cell_at(y-1, x-1), cell_at(y-1, x ), cell_at(y-1, x+1),
|
71
|
-
cell_at(y, x+1), cell_at(y , x-1),
|
72
|
-
cell_at(y+1, x-1), cell_at(y+1, x ), cell_at(y+1, x+1) ].compact
|
67
|
+
def neighbor_population_of(x: , y: )
|
68
|
+
ret = 0
|
69
|
+
min_x = x > 1 ? x - 1 : 0
|
70
|
+
max_x = x < width - 2 ? x + 1 : width - 1
|
71
|
+
min_y = y > 1 ? y - 1 : 0
|
72
|
+
max_y = y < height - 2 ? y + 1 : height - 1
|
73
|
+
(min_y..max_y).each do |row|
|
74
|
+
(min_x..max_x).each do |col|
|
75
|
+
ret += 1 unless ((x == col && y == row) || @state[row][col] == 0)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
ret
|
73
79
|
end
|
74
|
-
|
75
80
|
end
|
76
81
|
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module CellularAutomata::GifWriter
|
2
|
+
class << self
|
3
|
+
def write(opts={})
|
4
|
+
@scale = opts[:scale]
|
5
|
+
@cell_width = scale**opts[:cell_scale]
|
6
|
+
@board = CellularAutomata::Board.new(width: opts[:width]/scale, height: opts[:height]/scale, rule: opts[:rule])
|
7
|
+
@gif = Magick::ImageList.new
|
8
|
+
@width = opts[:width]
|
9
|
+
@height = opts[:height]
|
10
|
+
@frames = opts[:frames]
|
11
|
+
write_gif('test.gif')
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
attr_reader :board, :scale, :cell_width, :frames, :writer, :height, :width
|
17
|
+
|
18
|
+
def write_gif(outfile)
|
19
|
+
frames.times do |i|
|
20
|
+
draw_frame
|
21
|
+
board.tick!
|
22
|
+
end
|
23
|
+
@gif.write(outfile)
|
24
|
+
end
|
25
|
+
|
26
|
+
def draw_frame
|
27
|
+
writer = Magick::Draw.new
|
28
|
+
frame = Magick::Image.new(width, height) do
|
29
|
+
self.background_color = '#000000'
|
30
|
+
end
|
31
|
+
board.each_cell do |cell|
|
32
|
+
prev_1 = board.history[0][cell.y][cell.x]
|
33
|
+
prev_2 = board.history[1][cell.y][cell.x]
|
34
|
+
color = '#000000'
|
35
|
+
if cell.alive?
|
36
|
+
color = '#FFFF00'
|
37
|
+
elsif prev_1.alive?
|
38
|
+
color = '#AAAA00'
|
39
|
+
elsif prev_2.alive?
|
40
|
+
color = '#444400'
|
41
|
+
end
|
42
|
+
writer.stroke color
|
43
|
+
writer.fill color
|
44
|
+
x1 = cell.x * scale**2
|
45
|
+
y1 = cell.y * scale**2
|
46
|
+
x2 = x1 + cell_width
|
47
|
+
y2 = y1 + cell_width
|
48
|
+
writer.rectangle(x1, y1, x2, y2)
|
49
|
+
end
|
50
|
+
writer.draw(frame)
|
51
|
+
@gif << frame
|
52
|
+
print '.'
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
@@ -14,9 +14,18 @@ class CellWindow < Gosu::Window
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def draw
|
17
|
-
board.each_cell do |
|
18
|
-
|
19
|
-
|
17
|
+
board.each_cell do |x, y|
|
18
|
+
prev_1 = board.history[0][y][x] == 1
|
19
|
+
prev_2 = board.history[1][y][x] == 1
|
20
|
+
color = Gosu::Color::BLACK
|
21
|
+
if board.state[y][x] == 1
|
22
|
+
color = Gosu::Color.argb(0xff_FFFF00)
|
23
|
+
elsif prev_1
|
24
|
+
color = Gosu::Color.argb(0xff_AAAA00)
|
25
|
+
elsif prev_2
|
26
|
+
color = Gosu::Color.argb(0xff_444400)
|
27
|
+
end
|
28
|
+
Gosu.draw_rect(x * scale**2, y * scale**2, cell_width, cell_width, color, 0, :default)
|
20
29
|
end
|
21
30
|
end
|
22
31
|
|
@@ -1,27 +1,24 @@
|
|
1
1
|
class CellularAutomata::Rule
|
2
2
|
def initialize(rule_string)
|
3
|
-
|
3
|
+
rules = rule_string.downcase.scan(/[bs]\d+/)
|
4
|
+
raise ArgumentError.new("Invalid rule string #{rule_string}") if rules.length != 2
|
5
|
+
birth = rules.select {|s| s.start_with?('b')}.first
|
6
|
+
survive = rules.select {|s| s.start_with?('s')}.first
|
7
|
+
@rule_array = rules_array_from birth: birth, survive: survive
|
4
8
|
end
|
5
9
|
|
6
10
|
def process(input)
|
7
|
-
return @
|
8
|
-
end
|
9
|
-
|
10
|
-
def process2(input)
|
11
|
-
@rule_hash[input] != :die!
|
11
|
+
return @rule_array[input.to_i] || raise(ArgumentError.new("I don't know what to do with #{input.class} #{input}"))
|
12
12
|
end
|
13
13
|
|
14
14
|
private
|
15
15
|
|
16
|
-
def
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
death = ((0..8).to_a - birth) - survive
|
23
|
-
{live!: birth, survive!: survive, die!: death}.each_with_object({}) do |(k, v), ret|
|
24
|
-
v.each {|int| ret[int] = k}
|
16
|
+
def rules_array_from(birth: , survive: )
|
17
|
+
('0'..'8').each_with_object([]) do |i_str, ret|
|
18
|
+
val = :die
|
19
|
+
val = :survive if survive.include? i_str
|
20
|
+
val = :birth if birth.include? i_str
|
21
|
+
ret << val
|
25
22
|
end
|
26
23
|
end
|
27
24
|
end
|
data/lib/cellular_automata.rb
CHANGED
@@ -2,11 +2,14 @@ require 'pry'
|
|
2
2
|
require 'byebug'
|
3
3
|
require 'pry-byebug'
|
4
4
|
require 'gosu'
|
5
|
+
require 'rmagick'
|
5
6
|
require "cellular_automata/version"
|
6
7
|
require "cellular_automata/cell"
|
7
8
|
require "cellular_automata/rule"
|
8
9
|
require "cellular_automata/board"
|
9
10
|
require "cellular_automata/gui_window"
|
11
|
+
require "cellular_automata/gif_writer"
|
12
|
+
require 'cellular_c.bundle'
|
10
13
|
|
11
14
|
module CellularAutomata
|
12
15
|
end
|
metadata
CHANGED
@@ -1,20 +1,23 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cellular_automata
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Forrest Fleming
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-07-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: gosu
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
- - ">="
|
18
21
|
- !ruby/object:Gem::Version
|
19
22
|
version: '0.9'
|
20
23
|
type: :runtime
|
@@ -22,28 +25,31 @@ dependencies:
|
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
23
26
|
requirements:
|
24
27
|
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- - ">="
|
25
31
|
- !ruby/object:Gem::Version
|
26
32
|
version: '0.9'
|
27
33
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
34
|
+
name: rmagick
|
29
35
|
requirement: !ruby/object:Gem::Requirement
|
30
36
|
requirements:
|
31
37
|
- - "~>"
|
32
38
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
39
|
+
version: '2'
|
34
40
|
- - ">="
|
35
41
|
- !ruby/object:Gem::Version
|
36
|
-
version: '
|
37
|
-
type: :
|
42
|
+
version: '2.15'
|
43
|
+
type: :runtime
|
38
44
|
prerelease: false
|
39
45
|
version_requirements: !ruby/object:Gem::Requirement
|
40
46
|
requirements:
|
41
47
|
- - "~>"
|
42
48
|
- !ruby/object:Gem::Version
|
43
|
-
version: '
|
49
|
+
version: '2'
|
44
50
|
- - ">="
|
45
51
|
- !ruby/object:Gem::Version
|
46
|
-
version: '
|
52
|
+
version: '2.15'
|
47
53
|
- !ruby/object:Gem::Dependency
|
48
54
|
name: bundler
|
49
55
|
requirement: !ruby/object:Gem::Requirement
|
@@ -64,6 +70,26 @@ dependencies:
|
|
64
70
|
- - ">="
|
65
71
|
- !ruby/object:Gem::Version
|
66
72
|
version: '1.8'
|
73
|
+
- !ruby/object:Gem::Dependency
|
74
|
+
name: rake-compiler
|
75
|
+
requirement: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - "~>"
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '0'
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0.9'
|
83
|
+
type: :development
|
84
|
+
prerelease: false
|
85
|
+
version_requirements: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
- - ">="
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '0.9'
|
67
93
|
- !ruby/object:Gem::Dependency
|
68
94
|
name: rake
|
69
95
|
requirement: !ruby/object:Gem::Requirement
|
@@ -125,8 +151,11 @@ email:
|
|
125
151
|
- ffleming@gmail.com
|
126
152
|
executables:
|
127
153
|
- cell
|
154
|
+
- cell_console
|
155
|
+
- cell_gif
|
128
156
|
- cell_gui
|
129
|
-
extensions:
|
157
|
+
extensions:
|
158
|
+
- ext/cellular_c/extconf.rb
|
130
159
|
extra_rdoc_files: []
|
131
160
|
files:
|
132
161
|
- ".gitignore"
|
@@ -136,11 +165,16 @@ files:
|
|
136
165
|
- README.md
|
137
166
|
- Rakefile
|
138
167
|
- bin/cell
|
168
|
+
- bin/cell_console
|
169
|
+
- bin/cell_gif
|
139
170
|
- bin/cell_gui
|
140
171
|
- cellular_automata.gemspec
|
172
|
+
- ext/cellular_c/cellular_c.c
|
173
|
+
- ext/cellular_c/extconf.rb
|
141
174
|
- lib/cellular_automata.rb
|
142
175
|
- lib/cellular_automata/board.rb
|
143
176
|
- lib/cellular_automata/cell.rb
|
177
|
+
- lib/cellular_automata/gif_writer.rb
|
144
178
|
- lib/cellular_automata/gui_window.rb
|
145
179
|
- lib/cellular_automata/rule.rb
|
146
180
|
- lib/cellular_automata/version.rb
|
@@ -164,7 +198,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
164
198
|
version: '0'
|
165
199
|
requirements: []
|
166
200
|
rubyforge_project:
|
167
|
-
rubygems_version: 2.
|
201
|
+
rubygems_version: 2.4.7
|
168
202
|
signing_key:
|
169
203
|
specification_version: 4
|
170
204
|
summary: A simulation of cellular automata
|