life_game_viewer 0.9.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.
- data/.gitignore +19 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +233 -0
- data/Rakefile +2 -0
- data/bin/life_view_sample +6 -0
- data/lib/life_game_viewer/model/life_calculator.rb +103 -0
- data/lib/life_game_viewer/model/life_visualizer.rb +19 -0
- data/lib/life_game_viewer/model/model_validation.rb +41 -0
- data/lib/life_game_viewer/model/my_life_model.rb +56 -0
- data/lib/life_game_viewer/model/sample_life_model.rb +132 -0
- data/lib/life_game_viewer/version.rb +3 -0
- data/lib/life_game_viewer/view/actions.rb +193 -0
- data/lib/life_game_viewer/view/clipboard_helper.rb +55 -0
- data/lib/life_game_viewer/view/generations.rb +67 -0
- data/lib/life_game_viewer/view/life_game_viewer_frame.rb +293 -0
- data/lib/life_game_viewer/view/life_table_model.rb +97 -0
- data/lib/life_game_viewer/view/main.rb +16 -0
- data/lib/life_game_viewer.rb +27 -0
- data/life_game_viewer.gemspec +17 -0
- data/resources/images/alfred-e-neuman.jpg +0 -0
- data/spec/model/life_calculator_spec.rb +110 -0
- data/spec/model/life_visualizer_spec.rb +20 -0
- data/spec/model/model_validation_spec.rb +51 -0
- data/spec/model/sample_life_model_spec.rb +108 -0
- data/spec/spec_helper.rb +1 -0
- data/spec/view/generations_spec.rb +19 -0
- metadata +79 -0
@@ -0,0 +1,27 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
|
4
|
+
module LifeGameViewer
|
5
|
+
|
6
|
+
unless /java$/ === RUBY_PLATFORM
|
7
|
+
puts "This program must be run in JRuby."
|
8
|
+
exit -1
|
9
|
+
end
|
10
|
+
|
11
|
+
require 'java'
|
12
|
+
|
13
|
+
%w(
|
14
|
+
life_game_viewer/version.rb
|
15
|
+
life_game_viewer/model/life_calculator
|
16
|
+
life_game_viewer/model/life_visualizer
|
17
|
+
life_game_viewer/model/model_validation
|
18
|
+
life_game_viewer/model/sample_life_model
|
19
|
+
life_game_viewer/view/actions
|
20
|
+
life_game_viewer/view/clipboard_helper
|
21
|
+
life_game_viewer/view/generations
|
22
|
+
life_game_viewer/view/main
|
23
|
+
life_game_viewer/view/life_game_viewer_frame
|
24
|
+
life_game_viewer/view/life_table_model
|
25
|
+
).each { |file| require_relative(file) }
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/life_game_viewer/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Keith Bennett"]
|
6
|
+
gem.email = ["keithrbennett@gmail.com"]
|
7
|
+
gem.summary = "Game of Life Viewer"
|
8
|
+
gem.description = "Game of Life Viewer written in JRuby using Java Swing"
|
9
|
+
gem.homepage = 'https://github.com/keithrbennett/life_game_viewer'
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "life_game_viewer"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = LifeGameViewer::VERSION
|
17
|
+
end
|
Binary file
|
@@ -0,0 +1,110 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
|
3
|
+
require 'model/life_calculator'
|
4
|
+
require 'model/life_visualizer'
|
5
|
+
|
6
|
+
describe LifeCalculator do
|
7
|
+
|
8
|
+
subject { LifeCalculator.new }
|
9
|
+
|
10
|
+
# ============================================================
|
11
|
+
# Neighbors
|
12
|
+
# ============================================================
|
13
|
+
|
14
|
+
it "should return cells on both sides for a non-edge cell of a 1x5 board" do
|
15
|
+
model = SampleLifeModel.create(1, 5)
|
16
|
+
subject.neighbors(model, 0, 3).sort.should == [[0,2], [0,4]]
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should return 0,1 for 0,0 of a 1x5 board" do
|
20
|
+
model = SampleLifeModel.create(1, 5)
|
21
|
+
subject.neighbors(model, 0, 0).sort.should == [[0,1]]
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should return 0,3 for 0,4 of a 1x5 board" do
|
25
|
+
model = SampleLifeModel.create(1, 5)
|
26
|
+
subject.neighbors(model, 0, 4).sort.should == [[0,3]]
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should return 3 cells in the row above" do
|
30
|
+
model = SampleLifeModel.create(2, 5)
|
31
|
+
subject.neighbors(model, 1, 2).sort.should == \
|
32
|
+
[[0,1], [0,2], [0,3], [1,1], [1,3]]
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should return 3 cells in the row below" do
|
36
|
+
model = SampleLifeModel.create(2, 5)
|
37
|
+
subject.neighbors(model, 0, 2).sort.should == \
|
38
|
+
[[0,1], [0,3], [1,1], [1,2], [1,3]]
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should return 3 cells for lower left corner" do
|
42
|
+
model = SampleLifeModel.create(2, 5)
|
43
|
+
subject.neighbors(model, 1, 0).sort.should == \
|
44
|
+
[ [0,0], [0,1], [1,1] ]
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should return 3 cells for upper right corner" do
|
48
|
+
model = SampleLifeModel.create(2, 5)
|
49
|
+
subject.neighbors(model, 0, 4).sort.should == \
|
50
|
+
[ [0,3], [1,3], [1,4] ]
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should return 8 cells for a surrounded cell" do
|
54
|
+
model = SampleLifeModel.create(3, 3)
|
55
|
+
subject.neighbors(model, 1, 1).sort.should == \
|
56
|
+
[[0,0], [0,1], [0,2], [1,0], [1,2], [2,0], [2,1], [2,2]]
|
57
|
+
end
|
58
|
+
|
59
|
+
# ============================================================
|
60
|
+
# Dead Cell Calculations
|
61
|
+
# ============================================================
|
62
|
+
|
63
|
+
it "should calculate dead cell false correctly" do
|
64
|
+
model = SampleLifeModel.create_from_string("--*\n**-")
|
65
|
+
subject.dead_cell_should_become_alive(model, 0, 0).should be_false
|
66
|
+
subject.should_live(model, 0, 0).should be_false
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should calculate dead cell true correctly" do
|
70
|
+
model = SampleLifeModel.create_from_string("--*\n**-")
|
71
|
+
subject.dead_cell_should_become_alive(model, 0, 1).should be_true
|
72
|
+
subject.should_live(model, 0, 1).should be_true
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
# ============================================================
|
77
|
+
# Live Cell Calculations
|
78
|
+
# ============================================================
|
79
|
+
|
80
|
+
it "should calculate live cell false correctly" do
|
81
|
+
model = SampleLifeModel.create_from_string("--*\n**-")
|
82
|
+
subject.live_cell_should_continue_to_live(model, 1, 0).should be_false
|
83
|
+
subject.should_live(model, 1, 0).should be_false
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should calculate live cell true correctly" do
|
87
|
+
model = SampleLifeModel.create_from_string("--*\n**-")
|
88
|
+
subject.live_cell_should_continue_to_live(model, 1, 1).should be_true
|
89
|
+
subject.should_live(model, 1, 1).should be_true
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
# ============================================================
|
94
|
+
# Next Generation Model
|
95
|
+
# ============================================================
|
96
|
+
it "should return a next generation model different from the old" do
|
97
|
+
model = SampleLifeModel.create_from_string("--*\n**-")
|
98
|
+
next_gen_model = subject.next_generation(model)
|
99
|
+
next_gen_model.should_not == model
|
100
|
+
end
|
101
|
+
|
102
|
+
|
103
|
+
it "should return a correct next generation model" do
|
104
|
+
model = SampleLifeModel.create_from_string("--*\n**-")
|
105
|
+
next_gen_model = subject.next_generation(model)
|
106
|
+
expected_next_gen_model = SampleLifeModel.create_from_string("-*-\n-*-")
|
107
|
+
next_gen_model.should == expected_next_gen_model
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
|
3
|
+
require 'model/life_visualizer'
|
4
|
+
|
5
|
+
describe LifeVisualizer do
|
6
|
+
|
7
|
+
subject { LifeVisualizer.new }
|
8
|
+
let (:model) { SampleLifeModel.new(5, 8) }
|
9
|
+
|
10
|
+
it "should return a 5 line string" do
|
11
|
+
subject.to_display_string(model).count("\n").should == 5
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should return '*' for alive and '-' for dead" do
|
15
|
+
model = SampleLifeModel.create(1, 2)
|
16
|
+
model.set_living_state(0, 1, true)
|
17
|
+
subject.to_display_string(model).chomp.should == "-*"
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
require 'model/model_validation'
|
3
|
+
require 'model/sample_life_model'
|
4
|
+
|
5
|
+
describe ModelValidation do
|
6
|
+
|
7
|
+
subject { ModelValidation.new }
|
8
|
+
|
9
|
+
it "should return success on a model with all required methods" do
|
10
|
+
model = SampleLifeModel.create(1,1)
|
11
|
+
subject.methods_missing_message(model).should be_nil
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should correctly detect the absence of all instance methods" do
|
15
|
+
model = Object.new
|
16
|
+
methods_missing = subject.instance_methods_missing(model)
|
17
|
+
all_are_detected = subject.required_instance_methods.all? do |method|
|
18
|
+
methods_missing.include?(method)
|
19
|
+
end
|
20
|
+
all_are_detected.should be_true
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should correctly detect the absence of all class methods" do
|
24
|
+
model = Object.new
|
25
|
+
methods_missing = subject.class_methods_missing(model)
|
26
|
+
all_are_detected = subject.required_class_methods.all? do |method|
|
27
|
+
methods_missing.include?(method)
|
28
|
+
end
|
29
|
+
all_are_detected.should be_true
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should correctly detect the absence of all instance methods in message" do
|
33
|
+
model = Object.new
|
34
|
+
message = subject.methods_missing_message(model)
|
35
|
+
all_are_detected = subject.required_instance_methods.all? do |method|
|
36
|
+
message.include?(method.to_s)
|
37
|
+
end
|
38
|
+
all_are_detected.should be_true
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should correctly detect the absence of all class methods in message" do
|
42
|
+
model = Object.new
|
43
|
+
message = subject.methods_missing_message(model)
|
44
|
+
all_are_detected = subject.required_class_methods.all? do |method|
|
45
|
+
message.include?('self.' + method.to_s)
|
46
|
+
end
|
47
|
+
all_are_detected.should be_true
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
@@ -0,0 +1,108 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
|
3
|
+
require_relative '../spec_helper'
|
4
|
+
|
5
|
+
require 'model/sample_life_model'
|
6
|
+
|
7
|
+
describe SampleLifeModel do
|
8
|
+
|
9
|
+
subject { SampleLifeModel.create(12, 20) }
|
10
|
+
|
11
|
+
it "should be a SampleLifeModel" do
|
12
|
+
subject.should be_a SampleLifeModel
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should have 12 rows" do
|
16
|
+
subject.row_count.should == 12
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should have 20 columns" do
|
20
|
+
subject.column_count.should == 20
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should have all rows default to false" do
|
24
|
+
subject.data.flatten.any? { |obj| obj != false }.should be_false
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should have all rows default to not alive" do
|
28
|
+
any_alive = false
|
29
|
+
(0...subject.row_count).each do |rownum|
|
30
|
+
(0...subject.column_count).each do |colnum|
|
31
|
+
if subject.alive?(rownum, colnum)
|
32
|
+
any_alive = true
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
any_alive.should be_false
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should be able to set and get alive on a cell" do
|
40
|
+
subject.set_living_state(0, 0, true)
|
41
|
+
subject.alive?(0, 0).should be_true
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should set living state correctly using set_living_states" do
|
45
|
+
model = SampleLifeModel.create(3, 3)
|
46
|
+
cells_to_set_alive = [[0,0], [1,1], [2,2]]
|
47
|
+
model.set_living_states(cells_to_set_alive, true)
|
48
|
+
cells_to_set_alive.all? do |tuple|
|
49
|
+
row, col = tuple
|
50
|
+
model.alive?(row, col)
|
51
|
+
end.should be_true
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
it "should create a model from a string" do
|
56
|
+
s = "*.\n.*\n.."
|
57
|
+
model = SampleLifeModel.create_from_string(s);
|
58
|
+
|
59
|
+
model.row_count.should == 3
|
60
|
+
model.column_count.should == 2
|
61
|
+
model.alive?(0, 0).should be_true
|
62
|
+
model.alive?(0, 1).should be_false
|
63
|
+
model.alive?(1, 0).should be_false
|
64
|
+
model.alive?(1, 1).should be_true
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
it "should be considered == correctly" do
|
69
|
+
model_string = "*****\n-----\n*-*-*"
|
70
|
+
model1 = SampleLifeModel.create_from_string(model_string)
|
71
|
+
model2 = SampleLifeModel.create_from_string(model_string)
|
72
|
+
model1.should == model2
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should be considered != when row count is different" do
|
76
|
+
model1 = SampleLifeModel.create_from_string("*****\n-----\n*-*-*")
|
77
|
+
model2 = SampleLifeModel.create_from_string("*****\n-----")
|
78
|
+
model1.should_not == model2
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should be considered != when column count is different" do
|
82
|
+
model1 = SampleLifeModel.create_from_string("*****\n-----\n*-*-*")
|
83
|
+
model2 = SampleLifeModel.create_from_string("****\n----\n*-*-")
|
84
|
+
model1.should_not == model2
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should be considered != when an alive flag is different" do
|
88
|
+
model1 = SampleLifeModel.create_from_string("*****\n-----\n*-*-*")
|
89
|
+
model2 = SampleLifeModel.create_from_string("*****\n--*--\n*-*-*")
|
90
|
+
model1.should_not == model2
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should be able to use a passed block to initialize all cells to true" do
|
94
|
+
model = SampleLifeModel.create(3, 3) { |row, col| true }
|
95
|
+
model.number_living.should == 9
|
96
|
+
end
|
97
|
+
|
98
|
+
it "should be able to use a passed block to initialize all cells to false" do
|
99
|
+
model = SampleLifeModel.create(3, 3) { |row, col| false }
|
100
|
+
model.number_living.should == 0
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should be able to use a passed block to set only 1,2 to true" do
|
104
|
+
model = SampleLifeModel.create(3, 3) { |row, col| row == 1 && col == 2 }
|
105
|
+
(model.number_living.should == 1 && model.alive?(1, 2)).should be_true
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib', 'life_game_viewer')
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
require_relative '../spec_helper'
|
3
|
+
|
4
|
+
require 'view/generations'
|
5
|
+
require 'model/sample_life_model'
|
6
|
+
|
7
|
+
describe Generations do
|
8
|
+
|
9
|
+
it "should handle an empty 3x3 matrix correctly" do
|
10
|
+
life_model = SampleLifeModel.create(3, 3)
|
11
|
+
generations = Generations.new(life_model)
|
12
|
+
generations.current.should == life_model
|
13
|
+
generations.current_num.should == 0
|
14
|
+
end
|
15
|
+
|
16
|
+
# It's difficult to come up with tests for this class that don't really
|
17
|
+
# test the underlying model's next generation calculation.
|
18
|
+
end
|
19
|
+
|
metadata
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: life_game_viewer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.9.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Keith Bennett
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-09-11 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: Game of Life Viewer written in JRuby using Java Swing
|
15
|
+
email:
|
16
|
+
- keithrbennett@gmail.com
|
17
|
+
executables:
|
18
|
+
- life_view_sample
|
19
|
+
extensions: []
|
20
|
+
extra_rdoc_files: []
|
21
|
+
files:
|
22
|
+
- .gitignore
|
23
|
+
- Gemfile
|
24
|
+
- LICENSE
|
25
|
+
- README.md
|
26
|
+
- Rakefile
|
27
|
+
- bin/life_view_sample
|
28
|
+
- lib/life_game_viewer.rb
|
29
|
+
- lib/life_game_viewer/model/life_calculator.rb
|
30
|
+
- lib/life_game_viewer/model/life_visualizer.rb
|
31
|
+
- lib/life_game_viewer/model/model_validation.rb
|
32
|
+
- lib/life_game_viewer/model/my_life_model.rb
|
33
|
+
- lib/life_game_viewer/model/sample_life_model.rb
|
34
|
+
- lib/life_game_viewer/version.rb
|
35
|
+
- lib/life_game_viewer/view/actions.rb
|
36
|
+
- lib/life_game_viewer/view/clipboard_helper.rb
|
37
|
+
- lib/life_game_viewer/view/generations.rb
|
38
|
+
- lib/life_game_viewer/view/life_game_viewer_frame.rb
|
39
|
+
- lib/life_game_viewer/view/life_table_model.rb
|
40
|
+
- lib/life_game_viewer/view/main.rb
|
41
|
+
- life_game_viewer.gemspec
|
42
|
+
- resources/images/alfred-e-neuman.jpg
|
43
|
+
- spec/model/life_calculator_spec.rb
|
44
|
+
- spec/model/life_visualizer_spec.rb
|
45
|
+
- spec/model/model_validation_spec.rb
|
46
|
+
- spec/model/sample_life_model_spec.rb
|
47
|
+
- spec/spec_helper.rb
|
48
|
+
- spec/view/generations_spec.rb
|
49
|
+
homepage: https://github.com/keithrbennett/life_game_viewer
|
50
|
+
licenses: []
|
51
|
+
post_install_message:
|
52
|
+
rdoc_options: []
|
53
|
+
require_paths:
|
54
|
+
- lib
|
55
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
56
|
+
none: false
|
57
|
+
requirements:
|
58
|
+
- - ! '>='
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
61
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
62
|
+
none: false
|
63
|
+
requirements:
|
64
|
+
- - ! '>='
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '0'
|
67
|
+
requirements: []
|
68
|
+
rubyforge_project:
|
69
|
+
rubygems_version: 1.8.24
|
70
|
+
signing_key:
|
71
|
+
specification_version: 3
|
72
|
+
summary: Game of Life Viewer
|
73
|
+
test_files:
|
74
|
+
- spec/model/life_calculator_spec.rb
|
75
|
+
- spec/model/life_visualizer_spec.rb
|
76
|
+
- spec/model/model_validation_spec.rb
|
77
|
+
- spec/model/sample_life_model_spec.rb
|
78
|
+
- spec/spec_helper.rb
|
79
|
+
- spec/view/generations_spec.rb
|