conway_deathmatch 0.3.2.3 → 0.3.2.5
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/README.md +114 -0
- data/Rakefile +23 -0
- data/VERSION +1 -0
- data/conway_deathmatch.gemspec +28 -0
- data/lib/conway_deathmatch/board_state.rb +3 -4
- data/test/bench_board_state.rb +31 -0
- data/test/spec_helper.rb +22 -0
- data/test/test_board_state.rb +53 -0
- data/test/test_shapes.rb +15 -0
- metadata +10 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0c2b0b7a5f1a97dd224542429ceb5d288e61ed2f
|
4
|
+
data.tar.gz: 77d40e41599218e8e315a4661e77e37130a7187a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5686348c544509c2843456d23e3f296a77e38dd66705851b916a2998cc86e01bcf3310c7f3e86a4642e8a7bb47b8e20ecf2419b296068f6f125ad270e4195be1
|
7
|
+
data.tar.gz: d56b0a39e7a10760eef7abb8a13e6da5a24af3f3080def4e58d9c9bbafc3990a7be5e257d0d4487d967aabd7d53f82af682a918e0e24a1784c4594e69557fbe4
|
data/README.md
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
[](https://travis-ci.org/rickhull/conway_deathmatch)
|
2
|
+
[](http://badge.fury.io/rb/conway_deathmatch)
|
3
|
+
[](https://codeclimate.com/github/rickhull/conway_deathmatch)
|
4
|
+
[](https://gemnasium.com/rickhull/conway_deathmatch)
|
5
|
+
[](https://hakiri.io/github/rickhull/conway_deathmatch/master)
|
6
|
+
|
7
|
+
Introduction
|
8
|
+
===
|
9
|
+
|
10
|
+
[Conway's Game of Life](http://en.wikipedia.org/wiki/Conway%27s_Game_of_Life)
|
11
|
+
is a small, simple set of rules for
|
12
|
+
[cellular automata](http://en.wikipedia.org/wiki/Cellular_automaton).
|
13
|
+
Operating like a simulation, there is a starting state where certain points on
|
14
|
+
a 2 dimensional board are populated, and the rules of the game determine the
|
15
|
+
next state, generating interesting, unpredictable, and ultimately lifelike
|
16
|
+
patterns over time.
|
17
|
+
|
18
|
+
This project was inspired by http://gameoflifetotalwar.com/ (hereafter CGOLTW).
|
19
|
+
You should check it out. It updates the classic set of rules, which support
|
20
|
+
only a single population, for multiple populations which are able to compete
|
21
|
+
for space and population.
|
22
|
+
|
23
|
+
This project exists not to compete with CGOLTW but as a supplementary
|
24
|
+
project for exploration and learning. My initial motivation was to make a
|
25
|
+
"proving ground" for searching for simple shapes and patterns with high birth
|
26
|
+
rates for determining successful CGOLTW strategies.
|
27
|
+
|
28
|
+
Usage
|
29
|
+
===
|
30
|
+
|
31
|
+
Requirements
|
32
|
+
---
|
33
|
+
|
34
|
+
* Ruby 2.0 or newer (`__dir__` is used in the gemspec and for shape loading)
|
35
|
+
|
36
|
+
|
37
|
+
Install
|
38
|
+
---
|
39
|
+
|
40
|
+
gem install conway_deathmatch
|
41
|
+
|
42
|
+
Demo
|
43
|
+
---
|
44
|
+
|
45
|
+
# defaults to 70x40 board and an acorn shape
|
46
|
+
conway_deathmatch
|
47
|
+
|
48
|
+
# multiplayer
|
49
|
+
conway_deathmatch --one "acorn 30 30" --two "die_hard 20 10"
|
50
|
+
|
51
|
+
Available Shapes
|
52
|
+
---
|
53
|
+
|
54
|
+
[Definitions](https://github.com/rickhull/conway_deathmatch/blob/master/lib/conway_deathmatch/data/shapes.yaml)
|
55
|
+
|
56
|
+
* acorn
|
57
|
+
* beacon
|
58
|
+
* beehive
|
59
|
+
* blinker
|
60
|
+
* block
|
61
|
+
* block_engine_count (block engine, minimal point count)
|
62
|
+
* block_engine_space (block engine, minimal footprint)
|
63
|
+
* block_engine_stripe (block engine, 1 point tall)
|
64
|
+
* boat
|
65
|
+
* die_hard
|
66
|
+
* glider
|
67
|
+
* loaf
|
68
|
+
* lwss (lightweight spaceship)
|
69
|
+
* rpent (R-pentomino)
|
70
|
+
* swastika
|
71
|
+
* toad
|
72
|
+
|
73
|
+
Implementation
|
74
|
+
===
|
75
|
+
|
76
|
+
Just one file, aside from shape loading: [Have a look-see](https://github.com/rickhull/conway_deathmatch/blob/master/lib/conway_deathmatch/board_state.rb)
|
77
|
+
|
78
|
+
This implementation emphasizes simplicity and ease of understanding. Currently
|
79
|
+
there are no performance optimizations. I would like to use this project
|
80
|
+
to demonstrate the process of optimization, ideally adding optimization on
|
81
|
+
an optional, parallel, or otherwise non-permanent basis -- i.e. maintain the
|
82
|
+
simple, naive implementation for reference and correctness.
|
83
|
+
|
84
|
+
Inspiration
|
85
|
+
---
|
86
|
+
Coming into this project, I had significant background knowledge concerning
|
87
|
+
Conway's Game of Life, but I could not have recited the basic rules in any
|
88
|
+
form. After being inspired by competing in CGOLTW, I read their [one background
|
89
|
+
page](http://gameoflifetotalwar.com/how-to-play) and then the
|
90
|
+
[wikipedia page](http://en.wikipedia.org/wiki/Conway%27s_Game_of_Life). I
|
91
|
+
deliberately avoided any knowledge of any other implementations,
|
92
|
+
considering this project's implementation as of November 24 (2014) to be the
|
93
|
+
naive, simple approach.
|
94
|
+
|
95
|
+
Researched optimizations are now an immediate priority.
|
96
|
+
|
97
|
+
Caveats
|
98
|
+
---
|
99
|
+
|
100
|
+
### Boundaries
|
101
|
+
|
102
|
+
As currently implemented, this project uses fixed boundaries, and boundary
|
103
|
+
behavior is not standardized to my knowledge. For this project, points out of
|
104
|
+
bounds are treated as always-dead and unable-to-be-populated.
|
105
|
+
|
106
|
+
### Multiplayer
|
107
|
+
|
108
|
+
The rules for multiplayer are not standardized. I read about the CGOLTW
|
109
|
+
approach, and this project's approach is similar but different. In CGOLTW,
|
110
|
+
there are always 3 populations, and one population (civilians) is special, in
|
111
|
+
that civilians are born where there is birthright contention. Birthright
|
112
|
+
contention happens when a new cell must be generated, but none of the
|
113
|
+
neighboring parents have a unique plurality. For this project, birthright
|
114
|
+
contention is resolved with a random selection (TODO).
|
data/Rakefile
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'buildar'
|
2
|
+
|
3
|
+
Buildar.new do |b|
|
4
|
+
b.gemspec_file = 'conway_deathmatch.gemspec'
|
5
|
+
b.version_file = 'VERSION'
|
6
|
+
end
|
7
|
+
|
8
|
+
task default: %w[test bench]
|
9
|
+
|
10
|
+
require 'rake/testtask'
|
11
|
+
desc "Run tests"
|
12
|
+
Rake::TestTask.new do |t|
|
13
|
+
t.name = "test"
|
14
|
+
t.pattern = "test/test_*.rb"
|
15
|
+
# t.warning = true
|
16
|
+
end
|
17
|
+
|
18
|
+
desc "Run benchmarks"
|
19
|
+
Rake::TestTask.new do |t|
|
20
|
+
t.name = "bench"
|
21
|
+
t.pattern = "test/bench_*.rb"
|
22
|
+
# t.warning = true
|
23
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.3.2.5
|
@@ -0,0 +1,28 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'conway_deathmatch'
|
3
|
+
s.version = File.read(File.join(__dir__, 'VERSION')).chomp
|
4
|
+
s.summary = "Conway's Game of Life"
|
5
|
+
s.description = "Deathmatch"
|
6
|
+
s.authors = ["Rick Hull"]
|
7
|
+
s.homepage = 'https://github.com/rickhull/conway_deathmatch'
|
8
|
+
s.license = 'GPL'
|
9
|
+
s.files = [
|
10
|
+
'conway_deathmatch.gemspec',
|
11
|
+
'VERSION',
|
12
|
+
'Rakefile',
|
13
|
+
'README.md',
|
14
|
+
'lib/conway_deathmatch.rb',
|
15
|
+
'lib/conway_deathmatch/board_state.rb',
|
16
|
+
'lib/conway_deathmatch/shapes.rb',
|
17
|
+
'lib/conway_deathmatch/data/shapes.yaml',
|
18
|
+
'bin/conway_deathmatch',
|
19
|
+
'test/bench_board_state.rb',
|
20
|
+
'test/spec_helper.rb',
|
21
|
+
'test/test_board_state.rb',
|
22
|
+
'test/test_shapes.rb',
|
23
|
+
]
|
24
|
+
s.executables = ['conway_deathmatch']
|
25
|
+
s.add_development_dependency "buildar", "~> 2"
|
26
|
+
s.add_development_dependency "minitest", "~> 5"
|
27
|
+
s.required_ruby_version = "~> 2"
|
28
|
+
end
|
@@ -60,8 +60,8 @@ class ConwayDeathmatch::BoardState
|
|
60
60
|
(x-1..x+1).each { |xn|
|
61
61
|
next if outer_ring and !xn.between?(0, @x_len - 1)
|
62
62
|
(y-1..y+1).each { |yn|
|
63
|
-
next if outer_ring and !yn.between?(0, @y_len - 1)
|
64
|
-
|
63
|
+
next if (outer_ring and !yn.between?(0, @y_len - 1)) or
|
64
|
+
(xn == x and yn == y)
|
65
65
|
neighbors[@state[xn][yn]] += 1
|
66
66
|
}
|
67
67
|
}
|
@@ -85,8 +85,7 @@ class ConwayDeathmatch::BoardState
|
|
85
85
|
else
|
86
86
|
count = 0
|
87
87
|
neighbor_population(x, y).each { |sym, cnt|
|
88
|
-
|
89
|
-
count += cnt
|
88
|
+
count += cnt unless sym == DEAD
|
90
89
|
}
|
91
90
|
[count, ALIVE]
|
92
91
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'minitest/benchmark'
|
3
|
+
|
4
|
+
require 'conway_deathmatch'
|
5
|
+
|
6
|
+
include ConwayDeathmatch
|
7
|
+
|
8
|
+
BENCH_NEW_THRESH = (ENV['BENCH_NEW_THRESH'] || 0.9).to_f
|
9
|
+
BENCH_TICK_THRESH = (ENV['BENCH_TICK_THRESH'] || 0.9995).to_f
|
10
|
+
|
11
|
+
describe "BoardState.new Benchmark" do
|
12
|
+
bench_range do
|
13
|
+
bench_exp 9, 9999, 3
|
14
|
+
end
|
15
|
+
|
16
|
+
bench_performance_linear "width*height", BENCH_NEW_THRESH do |n|
|
17
|
+
BoardState.new(n, n)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "BoardState#tick Benchmark" do
|
22
|
+
bench_range do
|
23
|
+
bench_exp 1, 100, 3
|
24
|
+
end
|
25
|
+
|
26
|
+
bench_performance_linear "acorn demo", BENCH_TICK_THRESH do |n|
|
27
|
+
b = BoardState.new(70, 40)
|
28
|
+
Shapes.add(b, "acorn 50 18")
|
29
|
+
n.times { b.tick }
|
30
|
+
end
|
31
|
+
end
|
data/test/spec_helper.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'minitest/spec'
|
2
|
+
require 'minitest/autorun'
|
3
|
+
require 'conway_deathmatch'
|
4
|
+
|
5
|
+
include ConwayDeathmatch
|
6
|
+
|
7
|
+
DEAD = BoardState::DEAD
|
8
|
+
ALIVE = BoardState::ALIVE
|
9
|
+
|
10
|
+
SHAPE = "acorn"
|
11
|
+
SHAPE_STR = "#{SHAPE} 0 0"
|
12
|
+
POINTS_COUNT = 7
|
13
|
+
SHAPE_TICK_POINTS = [
|
14
|
+
[0, 1],
|
15
|
+
[1, 1],
|
16
|
+
[2, 1],
|
17
|
+
[4, 1],
|
18
|
+
[4, 2],
|
19
|
+
[5, 1],
|
20
|
+
[5, 2],
|
21
|
+
[5, 3],
|
22
|
+
]
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require_relative './spec_helper'
|
2
|
+
|
3
|
+
describe BoardState do
|
4
|
+
describe "an empty board" do
|
5
|
+
before do
|
6
|
+
@x = 5
|
7
|
+
@y = 5
|
8
|
+
@board = BoardState.new(@x, @y)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "must have dead population" do
|
12
|
+
@board.population[DEAD].must_equal @x * @y
|
13
|
+
@board.population.keys.length.must_equal 1
|
14
|
+
end
|
15
|
+
|
16
|
+
it "must still be dead after a tick" do
|
17
|
+
@board.tick.population[DEAD].must_equal @x*@y
|
18
|
+
@board.population.keys.length.must_equal 1
|
19
|
+
end
|
20
|
+
|
21
|
+
it "must accept a block" do
|
22
|
+
@board.populate 1,1
|
23
|
+
@board.populate 1,2
|
24
|
+
@board.populate 2,1
|
25
|
+
@board.populate 2,2
|
26
|
+
|
27
|
+
@board.population[DEAD].must_equal @x * @y - 4
|
28
|
+
@board.population[ALIVE].must_equal 4
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "adding shapes" do
|
33
|
+
before do
|
34
|
+
@board = BoardState.new(40, 40)
|
35
|
+
Shapes.add(@board, SHAPE_STR)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "must recognize \"#{SHAPE_STR}\"" do
|
39
|
+
Shapes.known.fetch(SHAPE).each { |xy_ary|
|
40
|
+
@board.value(*xy_ary).must_equal ALIVE
|
41
|
+
}
|
42
|
+
@board.population.fetch(ALIVE).must_equal POINTS_COUNT
|
43
|
+
end
|
44
|
+
|
45
|
+
it "must tick correctly" do
|
46
|
+
@board.tick
|
47
|
+
SHAPE_TICK_POINTS.each { |xy_ary|
|
48
|
+
@board.value(*xy_ary).must_equal ALIVE
|
49
|
+
}
|
50
|
+
@board.population.fetch(ALIVE).must_equal SHAPE_TICK_POINTS.length
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
data/test/test_shapes.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require_relative './spec_helper'
|
2
|
+
|
3
|
+
describe Shapes do
|
4
|
+
it "must recognize #{SHAPE}" do
|
5
|
+
Shapes.known.fetch(SHAPE).must_be_instance_of Array
|
6
|
+
end
|
7
|
+
|
8
|
+
it "must confirm #{SHAPE} on the board" do
|
9
|
+
@board = BoardState.new(20, 20)
|
10
|
+
Shapes.add(@board, SHAPE_STR)
|
11
|
+
Shapes.known.fetch(SHAPE).each { |xy_ary|
|
12
|
+
@board.value(*xy_ary).must_equal ALIVE
|
13
|
+
}
|
14
|
+
end
|
15
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: conway_deathmatch
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.2.
|
4
|
+
version: 0.3.2.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rick Hull
|
@@ -45,11 +45,19 @@ executables:
|
|
45
45
|
extensions: []
|
46
46
|
extra_rdoc_files: []
|
47
47
|
files:
|
48
|
+
- README.md
|
49
|
+
- Rakefile
|
50
|
+
- VERSION
|
48
51
|
- bin/conway_deathmatch
|
52
|
+
- conway_deathmatch.gemspec
|
49
53
|
- lib/conway_deathmatch.rb
|
50
54
|
- lib/conway_deathmatch/board_state.rb
|
51
55
|
- lib/conway_deathmatch/data/shapes.yaml
|
52
56
|
- lib/conway_deathmatch/shapes.rb
|
57
|
+
- test/bench_board_state.rb
|
58
|
+
- test/spec_helper.rb
|
59
|
+
- test/test_board_state.rb
|
60
|
+
- test/test_shapes.rb
|
53
61
|
homepage: https://github.com/rickhull/conway_deathmatch
|
54
62
|
licenses:
|
55
63
|
- GPL
|
@@ -60,7 +68,7 @@ require_paths:
|
|
60
68
|
- lib
|
61
69
|
required_ruby_version: !ruby/object:Gem::Requirement
|
62
70
|
requirements:
|
63
|
-
- - "
|
71
|
+
- - "~>"
|
64
72
|
- !ruby/object:Gem::Version
|
65
73
|
version: '2'
|
66
74
|
required_rubygems_version: !ruby/object:Gem::Requirement
|