abstracta 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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0043fdb30274ff1358134faba36ca65fe1971b0b
4
+ data.tar.gz: 5849ff0ba9bfdcbf456bcc8dc9064c0355fd4d85
5
+ SHA512:
6
+ metadata.gz: cf7f94c1a615120254e67fe7f9e300e8ce08e99049a7443caccf2ece1dd0b21d32a5b0ca486054b21b2fe01bec7541fcc9cdd0998c49a35dfff70e866d7debf4
7
+ data.tar.gz: e37136b39af3e646a512acdfdce15da0488cc7641028c6332b277113e8aa7ef78862f046e22381085f3763dabf08915e17d7aab51ef03e22d4d573f2cf6897ab
@@ -0,0 +1,7 @@
1
+ :directories:
2
+ - lib
3
+ :excludes:
4
+ - spec
5
+ - config/initializers
6
+ - vendor/bundle
7
+ :threshold: 95
@@ -0,0 +1,3 @@
1
+ -
2
+ ChangeLog.md
3
+ LICENSE.txt
@@ -0,0 +1,9 @@
1
+ Gemfile.lock
2
+ doc/
3
+ pkg/
4
+ vendor/
5
+ coverage/
6
+ tags
7
+ .bundle/
8
+ .rvmrc
9
+ **/.*.swp
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --colour --format documentation
@@ -0,0 +1 @@
1
+ 2.1.5
@@ -0,0 +1 @@
1
+ --markup markdown --title "abstracta Documentation" --protected
@@ -0,0 +1,4 @@
1
+ ### 0.1.0 / 2014-12-05
2
+
3
+ * Initial release:
4
+
data/Gemfile ADDED
@@ -0,0 +1,15 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ gem "straightedge"
6
+ gem "activesupport"
7
+
8
+ group :development do
9
+ gem "rack-test"
10
+ gem "rake"
11
+ gem "rspec"
12
+ gem "rspec-its"
13
+ gem "coco"
14
+ gem "pry"
15
+ end
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2014 Joseph Weissman
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,83 @@
1
+ ## abstracta
2
+
3
+ [![Codeship Badge](https://codeship.com/projects/3d50a570-6c46-0132-a8ac-2258e2e8174d/status?branch=master)](https://codeship.com/projects/54005)
4
+ [![Code Climate](https://codeclimate.com/github/jweissman/abstracta/badges/gpa.svg)](https://codeclimate.com/github/jweissman/abstracta)
5
+
6
+ * [Homepage](https://rubygems.org/gems/abstracta)
7
+ * [Documentation](http://rubydoc.info/gems/abstracta/frames)
8
+ * [Email](mailto:jweissman1986 at gmail.com)
9
+
10
+ ## Description
11
+
12
+ Cellular automata framework for ruby
13
+
14
+ ## Features
15
+
16
+ ## Examples
17
+
18
+ Again, intentionally abstract, so there's not much output you can
19
+ derive directly from interacting with it. It might go something like
20
+ this:
21
+
22
+ require 'abstracta'
23
+ world = Abstracta::World.new # creates a sim space
24
+ 100.times { world.step } # iterates/grows organisms
25
+
26
+ In any particular case you'll want to extend from these classes and build on top of
27
+ them. A concrete example from the Biosphere game (probably the place
28
+ to go right now for something to look at around this/inspiration):
29
+
30
+ class Cell < Abstracta::Occupant
31
+ def coordinates(cell_size=1)
32
+ x, y = cell.x * self.cell_size, cell.y * self.cell_size
33
+ x1, y1 = x + self.cell_size, y + self.cell_size
34
+ [[x,y], [x1,y], [x, y1], [x1,y1]]
35
+ end
36
+
37
+ def render(window, color=Gosu::Color::WHITE)
38
+ coords = coordinates(window.cell_size)
39
+ quad_args = coords.map{|c| c + [color] }
40
+ draw_quad(*quad_args)
41
+ end
42
+ end
43
+
44
+ ## Requirements
45
+
46
+ Everything gosu needs, which is really not all that bad. But it's not exactly portable,
47
+ or easy stand up a dev environment through a simple provisioning script (though maybe a
48
+ little focused effort there could help containerize it.)
49
+
50
+ ## Install
51
+
52
+ $ gem install biosphere
53
+
54
+ ## Synopsis
55
+
56
+ $ biosphere
57
+
58
+ ## Copyright
59
+
60
+ Copyright (c) 2014 Joseph Weissman
61
+
62
+ See {file:LICENSE.txt} for details. Abstracta
63
+
64
+ Cellular automata game :)
65
+
66
+ The idea is to have a game server where different players' organisms
67
+ could interact...
68
+
69
+
70
+ # Dependencies
71
+
72
+ You will need to
73
+
74
+ brew install sdl2 libogg libvorbis
75
+
76
+ for Gosu's dependencies. Then bundle and rake to play.
77
+
78
+ Ideally we'll get vagrant setup to build a dev environment for us...
79
+
80
+ (Eventually we'll want to containerize the server application too,
81
+ although that can be headless... A containerized dev environment
82
+ makes sense eventually too once that is reified a bit further. Something
83
+ like boxen may not be the worst thing to think about eventually there too.)
@@ -0,0 +1,35 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+
5
+ begin
6
+ require 'bundler'
7
+ rescue LoadError => e
8
+ warn e.message
9
+ warn "Run `gem install bundler` to install Bundler."
10
+ exit(-1)
11
+ end
12
+
13
+ begin
14
+ Bundler.setup(:development)
15
+ rescue Bundler::BundlerError => e
16
+ warn e.message
17
+ warn "Run `bundle install` to install missing gems."
18
+ exit e.status_code
19
+ end
20
+
21
+ require 'rake'
22
+
23
+ require 'rubygems/tasks'
24
+ Gem::Tasks.new
25
+
26
+ require 'rspec/core/rake_task'
27
+ RSpec::Core::RakeTask.new
28
+
29
+ task :test => :spec
30
+ task :default => :spec
31
+
32
+ require 'yard'
33
+ YARD::Rake::YardocTask.new
34
+ task :doc => :yard
35
+
@@ -0,0 +1,60 @@
1
+ # encoding: utf-8
2
+
3
+ require 'yaml'
4
+
5
+ Gem::Specification.new do |gem|
6
+ gemspec = YAML.load_file('gemspec.yml')
7
+
8
+ gem.name = gemspec.fetch('name')
9
+ gem.version = gemspec.fetch('version') do
10
+ lib_dir = File.join(File.dirname(__FILE__),'lib')
11
+ $LOAD_PATH << lib_dir unless $LOAD_PATH.include?(lib_dir)
12
+
13
+ require 'abstracta/version'
14
+ Abstracta::VERSION
15
+ end
16
+
17
+ gem.summary = gemspec['summary']
18
+ gem.description = gemspec['description']
19
+ gem.licenses = Array(gemspec['license'])
20
+ gem.authors = Array(gemspec['authors'])
21
+ gem.email = gemspec['email']
22
+ gem.homepage = gemspec['homepage']
23
+
24
+ glob = lambda { |patterns| gem.files & Dir[*patterns] }
25
+
26
+ gem.files = `git ls-files`.split($/)
27
+ gem.files = glob[gemspec['files']] if gemspec['files']
28
+
29
+ gem.executables = gemspec.fetch('executables') do
30
+ glob['bin/*'].map { |path| File.basename(path) }
31
+ end
32
+ gem.default_executable = gem.executables.first if Gem::VERSION < '1.7.'
33
+
34
+ gem.extensions = glob[gemspec['extensions'] || 'ext/**/extconf.rb']
35
+ gem.test_files = glob[gemspec['test_files'] || '{test/{**/}*_test.rb']
36
+ gem.extra_rdoc_files = glob[gemspec['extra_doc_files'] || '*.{txt,md}']
37
+
38
+ gem.require_paths = Array(gemspec.fetch('require_paths') {
39
+ %w[ext lib].select { |dir| File.directory?(dir) }
40
+ })
41
+
42
+ gem.requirements = gemspec['requirements']
43
+ gem.required_ruby_version = gemspec['required_ruby_version']
44
+ gem.required_rubygems_version = gemspec['required_rubygems_version']
45
+ gem.post_install_message = gemspec['post_install_message']
46
+
47
+ split = lambda { |string| string.split(/,\s*/) }
48
+
49
+ if gemspec['dependencies']
50
+ gemspec['dependencies'].each do |name,versions|
51
+ gem.add_dependency(name,split[versions])
52
+ end
53
+ end
54
+
55
+ if gemspec['development_dependencies']
56
+ gemspec['development_dependencies'].each do |name,versions|
57
+ gem.add_development_dependency(name,split[versions])
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ root = File.expand_path(File.join(File.dirname(__FILE__),'..'))
4
+ if File.directory?(File.join(root,'.git'))
5
+ Dir.chdir(root) do
6
+ begin
7
+ require 'bundler/setup'
8
+ rescue LoadError => e
9
+ warn e.message
10
+ warn "Run `gem install bundler` to install Bundler"
11
+ exit(-1)
12
+ end
13
+ end
14
+ end
15
+
16
+ require 'abstracta'
17
+
18
+ # TODO sim process...
File without changes
@@ -0,0 +1 @@
1
+ Feature: Simulating the game of life...
File without changes
@@ -0,0 +1,18 @@
1
+ name: abstracta
2
+ summary: "a cellular automation and simulation services library in Ruby"
3
+ description: "a modular cellular automata engine with the goal of providing a simulation service framework"
4
+ license: MIT
5
+ authors: Joseph Weissman
6
+ email: jweissman1986@gmail.com
7
+ homepage: https://rubygems.org/gems/abstracta
8
+
9
+ dependencies:
10
+ activesupport: ~> 4.2.0
11
+ straightedge: ~> 0.1.0
12
+
13
+ development_dependencies:
14
+ bundler: ~> 1.0
15
+ rake: ~> 0.8
16
+ rspec: ~> 2.4
17
+ rubygems-tasks: ~> 0.2
18
+ yard: ~> 0.8
@@ -0,0 +1,18 @@
1
+ require 'ostruct'
2
+
3
+ require 'straightedge'
4
+
5
+ require 'abstracta/version'
6
+ require 'abstracta/occupant'
7
+ require 'abstracta/territory'
8
+ require 'abstracta/genome'
9
+ require 'abstracta/world'
10
+ require 'abstracta/developer'
11
+ require 'abstracta/extend/range'
12
+
13
+ module Abstracta
14
+ include Straightedge
15
+ def self.bootstrap!(opts={},&blk)
16
+ Engine.boot(opts,&blk)
17
+ end
18
+ end
@@ -0,0 +1,52 @@
1
+ module Abstracta
2
+ class Developer
3
+ extend Forwardable
4
+ def initialize(entity)
5
+ @entity = entity
6
+ end
7
+
8
+ def collection; [] end
9
+
10
+ def tick
11
+ @entity.age!
12
+ end
13
+
14
+ def step(*args)
15
+ tick
16
+ develop(*args)
17
+ collection.map(&:step)
18
+ end
19
+ end
20
+
21
+ class WorldDeveloper < Developer
22
+ def world; @entity end
23
+ def collection; world.territories end
24
+
25
+ def develop
26
+ # now a no-op...
27
+ end
28
+ end
29
+
30
+ class TerritoryDeveloper < Developer
31
+ def_delegators :territory, :age, :size, :period, :limit, :[], :each, :first,
32
+ :occupy!, :adjacent, :growth, :cull!
33
+
34
+ def territory; @entity end
35
+ def collection; territory.occupants end
36
+
37
+ def develop(targets: adjacent)
38
+ grow(targets) if growth_indicated?
39
+ cull!
40
+ end
41
+
42
+ def growth_indicated?
43
+ in_cycle = age % territory.period == 0
44
+ under_bound = size <= territory.limit
45
+ in_cycle && under_bound
46
+ end
47
+
48
+ def grow(targets, n=growth)
49
+ targets.sample(n).map(&method(:occupy!))
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,5 @@
1
+ class Range
2
+ def sample
3
+ to_a.sample
4
+ end
5
+ end
@@ -0,0 +1,31 @@
1
+ module Abstracta
2
+ class Genome < OpenStruct
3
+ def self.default
4
+ @default_genome ||= OpenStruct.new(
5
+ #growth_cycle: (2..10).sample,
6
+ #growth_limit: (4..20).sample,
7
+ #growth_radius: (1..4).sample,
8
+ #growth_rate: (15..100).sample / 10.0,
9
+
10
+ growth: OpenStruct.new(
11
+ cycle: 2, #(2..4).sample,
12
+ limit: 100, #(20..80).sample,
13
+ #radius: (1..2).sample,
14
+ rate: OpenStruct.new(
15
+ additive: 2,
16
+ multiplicative: 1.05
17
+ )
18
+ #2, #(1..4).sample #(150..200).sample / 100.0,
19
+ ),
20
+
21
+ # TODO make these do something!
22
+ age_bound: 20 #(3..9).sample,
23
+ #influence_radius: 10,
24
+ #sterile: false,
25
+ #sticky: false,
26
+ #vision_radius: 100,
27
+ #mobile: true,
28
+ )
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,20 @@
1
+ module Abstracta
2
+ class Occupant
3
+ extend Forwardable
4
+ attr_reader :age
5
+ attr_reader :location
6
+ def_delegators :location, :zip, :x, :y
7
+
8
+ def initialize(location=[0,0])
9
+ @location = location
10
+ @age = 0
11
+ @size = 1
12
+ end
13
+
14
+ def position; [@x,@y] end
15
+
16
+ def step
17
+ @age = @age + 1
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,63 @@
1
+ module Abstracta
2
+ class Territory
3
+ include Enumerable
4
+ extend Forwardable
5
+
6
+ def_delegators :occupants, :[], :size, :each, :include?, :adjacent
7
+ def_delegator :developer, :step
8
+
9
+ alias :occupy? :include?
10
+
11
+ attr_reader :dna
12
+ attr_reader :occupants
13
+ attr_reader :compass, :developer
14
+ attr_reader :age
15
+ attr_reader :period, :limit
16
+
17
+ def initialize(locations=[[0,0]],genome=Genome.default)
18
+ @compass = Compass.default
19
+ @occupants = locations.map(&method(:occupant_at))
20
+
21
+ @dna = genome.tap do |my|
22
+ @period = my.growth.cycle
23
+ @rate = my.growth.rate
24
+ @limit = my.growth.limit
25
+ @max_age = my.age_bound
26
+ end
27
+
28
+ @age = 0
29
+
30
+ @developer = TerritoryDeveloper.new(self)
31
+ end
32
+
33
+ def age!
34
+ @age = @age + 1
35
+ end
36
+
37
+ def projected_size
38
+ (@rate.additive + size) * @rate.multiplicative
39
+ end
40
+
41
+ def growth
42
+ projected_size - size
43
+ end
44
+
45
+ def occupant_class
46
+ Occupant
47
+ end
48
+
49
+ def occupant_at(point)
50
+ occupant_class.new([point.x, point.y])
51
+ end
52
+
53
+ def occupy!(target)
54
+ @occupants << occupant_at(target)
55
+ end
56
+
57
+ def cull!
58
+ @occupants.reject! do |occupant|
59
+ occupant.age >= @max_age
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,10 @@
1
+ module Abstracta
2
+ VERSION = "0.1.1"
3
+ RELEASE = "prealpha"
4
+ CRYPTONYM = "aqua-prism"
5
+ AUTHOR = "Joseph Weissman <jweissman1986@gmail.com>"
6
+
7
+ def self.version
8
+ "v#{VERSION}-#{RELEASE} \"#{CRYPTONYM}\", (c) #{Date.today.year} #{AUTHOR}"
9
+ end
10
+ end
@@ -0,0 +1,75 @@
1
+ module Abstracta
2
+ class World
3
+ extend Forwardable
4
+ attr_reader :age, :grid, :territories, :developer
5
+
6
+ def_delegators :grid, :width, :height
7
+ def_delegators :developer, :step
8
+ #def_delegators :compass, :distance_from
9
+
10
+ def initialize(geometry=[100,100], opts={})
11
+ @grid = Grid.new(geometry)
12
+ #@compass = Compass.default
13
+ @density = opts.delete(:density) { 0.05 }
14
+
15
+ @territory_count = opts.delete(:territory_count) { width * height * @density }
16
+ @territories = []
17
+ @territories = create_territories(@territory_count)
18
+ update_map
19
+
20
+ @age = 0
21
+
22
+ @developer = WorldDeveloper.new(self)
23
+ end
24
+
25
+ def update_map
26
+ @occupied = compute_occupied
27
+ end
28
+
29
+ def territory_class; Territory end
30
+ def create_territories(n=1)
31
+ seeds = @grid.sample(n)
32
+ Array.new(n) { territory_class.new([seeds.pop]) }
33
+ end
34
+
35
+ def age!
36
+ @age = @age + 1
37
+ end
38
+
39
+ #def step
40
+ # old_size = occupied.size
41
+ # update_territories
42
+ # occupied.size - old_size
43
+ #end
44
+
45
+ #def update_territories
46
+ # @territories.each do |territory|
47
+ # update_map
48
+ # targets = compute_projected_targets(territory)
49
+ # territory.step(targets)
50
+ # end
51
+ #end
52
+
53
+ def occupied
54
+ @occupied ||= compute_occupied
55
+ end
56
+
57
+ def compute_occupied
58
+ territories.map(&:occupants).flatten.map(&:location)
59
+ end
60
+
61
+ def occupied?(xy)
62
+ @occupied.include?(xy)
63
+ end
64
+
65
+ def compute_projected_targets(territory, n=territory.growth)
66
+ available_adjacent(territory).take(n)
67
+ end
68
+
69
+ def available_adjacent(territory)
70
+ @grid.clip territory.adjacent.reject(&method(:occupied?)) # { |xy| occupied.include?(xy) } # & available # - occupied
71
+ end
72
+ end
73
+ end
74
+
75
+ #
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/enb ruby
2
+
3
+ #
4
+ root = File.expand_path(File.join(File.dirname(__FILE__),'..'))
5
+ if File.directory?(File.join(root,'.git'))
6
+ Dir.chdir(root) do
7
+ begin
8
+ require 'bundler/setup'
9
+ require 'abstracta'
10
+ Engine.boot
11
+ rescue LoadError => e
12
+ warn e.message
13
+ warn "Run `gem install bundler` to install Bundler"
14
+ exit(-1)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+ require 'abstracta'
3
+
4
+ include Abstracta
5
+
6
+ describe TerritoryDeveloper do
7
+
8
+ let(:territory) { Territory.new }
9
+ subject { TerritoryDeveloper.new(territory) }
10
+
11
+ describe "#step" do
12
+ it "should age occupants" do
13
+ expect { subject.step }.to change { subject.first.age }.by 1
14
+ end
15
+
16
+ #it "should grow to a specific location" do
17
+ # expect { subject.step([[0,1]]) }.to change { subject.size }.by(1)
18
+ #end
19
+
20
+ let(:cycle) { subject.period }
21
+
22
+ it "should grow total size" do
23
+ expect { cycle.times { subject.step } }.to change { subject.size }.by(subject.growth.to_i)
24
+ end
25
+
26
+ context "longterm growth behaviors" do
27
+ before { cycle.times { subject.step }}
28
+
29
+ it 'should generate occupants with valid positions' do
30
+ subject.each do |occupant|
31
+ expect(occupant.x).to be_an(Integer)
32
+ expect(occupant.y).to be_an(Integer)
33
+ end
34
+ end
35
+
36
+ it "should grow a little bit" do
37
+ expect(subject.size).to be > 1
38
+ end
39
+
40
+ it "should not grow too much" do
41
+ expect(subject.size).not_to be > subject.limit
42
+ end
43
+ end
44
+ end
45
+ end
46
+
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+ require 'ostruct'
3
+ require 'abstracta/extend/range'
4
+ require 'abstracta/genome'
5
+
6
+ describe Abstracta::Genome do
7
+ subject { Abstracta::Genome.default }
8
+
9
+ context "defaults" do
10
+ it 'should have sane options' do
11
+ #expect(subject.mobile).to be(true)
12
+ #expect(subject.sterile).to be(false)
13
+ expect(subject.growth.limit).to be_an(Integer) #eql(10)
14
+ #expect(subject.growth.radius).to be_an(Integer) #eql(10)
15
+
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+ require 'straightedge'
3
+ require 'abstracta/occupant'
4
+
5
+ describe Abstracta::Occupant do
6
+ it 'should have a position' do
7
+ expect(subject.x).to be_an Integer
8
+ expect(subject.y).to be_an Integer
9
+ end
10
+
11
+ context "#age" do
12
+ it 'should be a year older' do
13
+ expect { subject.step }.to change { subject.age }.by 1
14
+ end
15
+ end
16
+
17
+ #it 'should have a genetic code' do
18
+ # expect(subject.dna).to be_a Abstracta::Genome
19
+ #end
20
+ end
21
+
22
+
@@ -0,0 +1,44 @@
1
+ require 'spec_helper'
2
+ require 'abstracta'
3
+
4
+ include Abstracta
5
+
6
+ describe Territory do
7
+ subject { Territory.new([[0,0]]) }
8
+
9
+ it 'should have dna' do
10
+ expect(subject.dna).to be_a OpenStruct
11
+ end
12
+
13
+ describe "#step" do
14
+ it "should age occupants" do
15
+ expect { subject.step }.to change { subject.first.age }.by 1
16
+ end
17
+
18
+ let(:cycle) { subject.dna.growth.cycle }
19
+
20
+ it "should grow total size" do
21
+ expect { cycle.times { subject.step } }.to change { subject.size }.by(subject.growth.to_i)
22
+ end
23
+
24
+ context "longterm growth behaviors" do
25
+ before { cycle.times { subject.step }}
26
+
27
+ it 'should generate occupants with valid positions' do
28
+ subject.occupants.each do |occupant|
29
+ expect(occupant.x).to be_an(Integer)
30
+ expect(occupant.y).to be_an(Integer)
31
+ end
32
+ end
33
+
34
+ it "should grow a little bit" do
35
+ expect(subject.size).to be > 1
36
+ end
37
+
38
+ it "should not grow too much" do
39
+ expect(subject.size).not_to be > subject.dna.growth.limit
40
+ end
41
+ end
42
+ end
43
+ end
44
+
@@ -0,0 +1,90 @@
1
+ require 'spec_helper'
2
+ require 'abstracta'
3
+
4
+ include Abstracta
5
+
6
+ describe World do
7
+ let(:width) { 100 }
8
+ let(:height) { 100 }
9
+ let(:geometry) { [width, height] }
10
+
11
+ subject { World.new(geometry, territory_count: 1) }
12
+
13
+ #let!(:field) { subject.field }
14
+ let!(:territory) { subject.territories.first }
15
+ #let!(:occupant) { subject.occupants.first }
16
+
17
+ it 'should have an age' do
18
+ expect(subject.age).to be_zero
19
+ end
20
+
21
+ it 'should generate a territory' do
22
+ expect(territory).to be_a(Territory)
23
+ expect(territory.size).to eql(1)
24
+ end
25
+
26
+ it 'should indicate what spaces is available' do
27
+ expect(subject.occupied.size).to eql(1)
28
+ end
29
+
30
+ #it "should construct a field" do
31
+ # expect(field.any?).to eql(true)
32
+ # expect(field.width).to eql(width)
33
+ # expect(field.height).to eql(height)
34
+ #end
35
+
36
+ context "territory creation" do
37
+ context "with a given density" do
38
+ let(:density) { 0.3 }
39
+ let(:projected_count) { (width * height * density).to_i }
40
+ subject { World.new(geometry, density: density) }
41
+ let!(:actual_territory_count) { subject.territories.count }
42
+
43
+ it "should have territories" do
44
+ expect(subject.territories).not_to be_empty
45
+ end
46
+
47
+ it "should have the projected number of territories" do
48
+ expect(actual_territory_count).to eql(projected_count) #width*height*density)
49
+ end
50
+
51
+ it "should generate Territory objects with nonzero size" do
52
+ expect(territory).to be_a(Territory)
53
+ expect(territory.size).to be > 0
54
+ end
55
+ end
56
+
57
+ context "with a specified count" do
58
+ N = 5
59
+ subject { World.new(geometry, territory_count: N) }
60
+ it "should have #{N} territories" do
61
+ expect(subject.territories.count).to eql(N)
62
+ expect(territory).to be_a(Territory)
63
+ end
64
+ end
65
+ end
66
+
67
+ #it "should be occupied" do
68
+ # expect(subject.occupants).not_to be_empty
69
+ # expect(occupant).to be_a(Occupant)
70
+ #end
71
+
72
+ context "#step" do
73
+ it 'should age the world' do
74
+ expect { subject.step }.to change { subject.age }.by(1)
75
+ end
76
+
77
+ context "growth" do
78
+ let(:n) { 10 }
79
+
80
+ before do
81
+ n.times { subject.step }
82
+ end
83
+
84
+ it 'should not have grown outside the territorial boundary' do
85
+ within_bounds = subject.occupied.all? { |p| subject.grid.include?(p) }
86
+ expect(within_bounds).to be(true)
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+ require 'abstracta'
3
+ include Abstracta
4
+
5
+ describe Abstracta do
6
+ describe "constants" do
7
+ it "should have a VERSION constant" do
8
+ expect(subject.version).to eql("v0.1.0-prealpha \"aqua-prism\", (c) 2014 Joseph Weissman <jweissman1986@gmail.com>")
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,6 @@
1
+ require 'coco'
2
+ require 'rspec'
3
+ require 'rspec/its'
4
+ require 'pry'
5
+
6
+ require 'profile' if ENV["PROFILE"] == "1"
@@ -0,0 +1,63 @@
1
+ # A discrete (ideally tuple-like) value at the
2
+ # boundaries between adapters and reactors
3
+ #class AbstractAdapter
4
+ # def initialize(rx)
5
+ # @reactor = rx
6
+ # end
7
+
8
+ # def drive
9
+ # @reactor.engine.turn
10
+ # end
11
+
12
+ # def handle(event)
13
+ # @reactor.react(event)
14
+ # end
15
+ #end
16
+
17
+ #class ConsoleAdapter
18
+ # def handle(event)
19
+
20
+ # end
21
+ #end
22
+
23
+ #class AbstractDisruptor
24
+ # include Disruptor::Processor
25
+
26
+ # def initialize(adapter)
27
+ # @adapter = adapter
28
+
29
+ # end
30
+
31
+ # def absorb(events)
32
+ # @adapter.handle(event)
33
+ # process_event(event)
34
+ # end
35
+
36
+ # def process_event(event)
37
+ # raise "implement in subclass"
38
+ # end
39
+ #end
40
+
41
+ #class SimpleDisruptor < AbstractDisruptor
42
+
43
+ #end
44
+
45
+
46
+ #class SimpleActor < AbstractReactor
47
+ # def perform(story) #name, *args, &blk)
48
+ # process(story.events)
49
+ # story.events.each do |event|
50
+ # @engine.adapt do |event|
51
+ # @disruptor.absorb(event)
52
+ # end
53
+ # end
54
+ # end
55
+ #end
56
+
57
+ #class WebsocketReactor < SimpleReactor
58
+ # def react(name, *args, &blk)
59
+ # raise 'not implemented'
60
+ # end
61
+ #end
62
+
63
+
metadata ADDED
@@ -0,0 +1,182 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: abstracta
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Joseph Weissman
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-12-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 4.2.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 4.2.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: straightedge
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.1.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.1.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.8'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.8'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '2.4'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '2.4'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rubygems-tasks
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '0.2'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0.2'
97
+ - !ruby/object:Gem::Dependency
98
+ name: yard
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '0.8'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '0.8'
111
+ description: a modular cellular automata engine with the goal of providing a simulation
112
+ service framework
113
+ email: jweissman1986@gmail.com
114
+ executables:
115
+ - abstracta
116
+ extensions: []
117
+ extra_rdoc_files:
118
+ - ChangeLog.md
119
+ - LICENSE.txt
120
+ - README.md
121
+ - thoughts.rb.txt
122
+ files:
123
+ - ".coco.yml"
124
+ - ".document"
125
+ - ".gitignore"
126
+ - ".rspec"
127
+ - ".ruby-version"
128
+ - ".yardopts"
129
+ - ChangeLog.md
130
+ - Gemfile
131
+ - LICENSE.txt
132
+ - README.md
133
+ - Rakefile
134
+ - abstracta.gemspec
135
+ - bin/abstracta
136
+ - features/.gitkeep
137
+ - features/abstracta.feature
138
+ - features/step_definitions/.gitkeep
139
+ - features/step_definitions/abstracta_steps.rb
140
+ - gemspec.yml
141
+ - lib/abstracta.rb
142
+ - lib/abstracta/developer.rb
143
+ - lib/abstracta/extend/range.rb
144
+ - lib/abstracta/genome.rb
145
+ - lib/abstracta/occupant.rb
146
+ - lib/abstracta/territory.rb
147
+ - lib/abstracta/version.rb
148
+ - lib/abstracta/world.rb
149
+ - script/bootstrap.rb
150
+ - spec/abstracta/developer_spec.rb
151
+ - spec/abstracta/genome_spec.rb
152
+ - spec/abstracta/occupant_spec.rb
153
+ - spec/abstracta/territory_spec.rb
154
+ - spec/abstracta/world_spec.rb
155
+ - spec/abstracta_spec.rb
156
+ - spec/spec_helper.rb
157
+ - thoughts.rb.txt
158
+ homepage: https://rubygems.org/gems/abstracta
159
+ licenses:
160
+ - MIT
161
+ metadata: {}
162
+ post_install_message:
163
+ rdoc_options: []
164
+ require_paths:
165
+ - lib
166
+ required_ruby_version: !ruby/object:Gem::Requirement
167
+ requirements:
168
+ - - ">="
169
+ - !ruby/object:Gem::Version
170
+ version: '0'
171
+ required_rubygems_version: !ruby/object:Gem::Requirement
172
+ requirements:
173
+ - - ">="
174
+ - !ruby/object:Gem::Version
175
+ version: '0'
176
+ requirements: []
177
+ rubyforge_project:
178
+ rubygems_version: 2.4.3
179
+ signing_key:
180
+ specification_version: 4
181
+ summary: a cellular automation and simulation services library in Ruby
182
+ test_files: []