abstracta 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []