jinni 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.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.travis.yml +3 -0
- data/Gemfile +6 -0
- data/README.md +62 -0
- data/Rakefile +1 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/jinni.gemspec +23 -0
- data/lib/jinni/creature.rb +90 -0
- data/lib/jinni/eigenclass.rb +69 -0
- data/lib/jinni/numeric.rb +12 -0
- data/lib/jinni/version.rb +3 -0
- data/lib/jinni.rb +26 -0
- metadata +86 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: e590fb000051d9d6745d00096924d0194c9927a5
|
4
|
+
data.tar.gz: c3768d8b17c550e001e2998e069f4c0417c895bf
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 4c1301f91f504bc9bf00de0e15d3fe6b6be9a2247c827411998c2d9d0f51d8b3d9126714225130efb21e1b8e82003af50f85f2190e71ce2c677c924120fe3513
|
7
|
+
data.tar.gz: 983d1196cad96ba6f0df36cbccbade483cf1b9dd62cc7b82816fd1ec0176f1a0df4b64df22afdb3776816b1e2bd475a08241cfc5d2ba3904db62051e99149d32
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
# Jinni []()
|
2
|
+
|
3
|
+
unconventional genetics, aggressively metaprogrammed
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'jinni'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install jinni
|
18
|
+
|
19
|
+
|
20
|
+
## Usage
|
21
|
+
|
22
|
+
### Start with some objects
|
23
|
+
|
24
|
+
class Fish < Jinni::Creature
|
25
|
+
# attr_genetic name, min, max
|
26
|
+
attr_genetic :pointiness, 0, 1
|
27
|
+
attr_genetic :mass_in_kilos, 10, 100
|
28
|
+
attr_genetic :speed_in_knots, 8, 12
|
29
|
+
|
30
|
+
# must return a fixnum
|
31
|
+
def fitness
|
32
|
+
@pointiness + ( @speed_in_knots / @mass_in_kilos )
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
fishes = []
|
37
|
+
10.times { fishes.push(Fish.random_new) } # `random_new` respects min and max
|
38
|
+
|
39
|
+
### Have an offspring
|
40
|
+
|
41
|
+
bill = fishes[0]
|
42
|
+
ted = fishes[1]
|
43
|
+
|
44
|
+
child = bill << ted
|
45
|
+
|
46
|
+
### ~~Start a whole new generation~~ lol not yet
|
47
|
+
|
48
|
+
this here doesn't work:
|
49
|
+
|
50
|
+
generation = Jinni.generate_from fishes
|
51
|
+
fishes << generation
|
52
|
+
|
53
|
+
### todo: something mutations something, also make it faster
|
54
|
+
|
55
|
+
|
56
|
+
## Contributing
|
57
|
+
|
58
|
+
1. Fork it ( https://github.com/amonks/jinni/fork )
|
59
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
60
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
61
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
62
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "jinni"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
data/jinni.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'jinni/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "jinni"
|
8
|
+
spec.version = Jinni::VERSION
|
9
|
+
spec.authors = ["Andrew Monks"]
|
10
|
+
spec.email = ["a@monks.co"]
|
11
|
+
|
12
|
+
spec.summary = %q{unconventional genetics, aggressively metaprogrammed [hideous code use at your own risk]}
|
13
|
+
spec.homepage = "http://github.com/amonks/jinni"
|
14
|
+
|
15
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
16
|
+
spec.bindir = "exe"
|
17
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
18
|
+
spec.require_paths = ["lib"]
|
19
|
+
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.9"
|
22
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
23
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
module Jinni
|
2
|
+
class Creature
|
3
|
+
attr_reader :genes
|
4
|
+
|
5
|
+
@@genes = Hash.new
|
6
|
+
|
7
|
+
# redefine this method in your class
|
8
|
+
def fitness
|
9
|
+
0.0
|
10
|
+
end
|
11
|
+
|
12
|
+
# getter for list of genes
|
13
|
+
def genes
|
14
|
+
@@genes
|
15
|
+
end
|
16
|
+
|
17
|
+
# this is Where It Happens
|
18
|
+
# usage:
|
19
|
+
# child = bill << ted
|
20
|
+
def cross(object)
|
21
|
+
binary_one = self.to_binary
|
22
|
+
binary_two = object.to_binary
|
23
|
+
|
24
|
+
raise "uh oh" if binary_one.length != binary_two.length
|
25
|
+
|
26
|
+
crossover_point = rand(binary_one.length)
|
27
|
+
|
28
|
+
output_one = binary_one[0..crossover_point - 1] << binary_two[crossover_point..-1]
|
29
|
+
output_two = binary_two[0..crossover_point - 1] << binary_one[crossover_point..-1]
|
30
|
+
|
31
|
+
binary = rand(1) == 1 ? output_one : output_two
|
32
|
+
|
33
|
+
Fish.new_from_binary(binary)
|
34
|
+
end
|
35
|
+
alias :<< :cross
|
36
|
+
|
37
|
+
# serialize object into binary, according to schema laid out in eigenclass
|
38
|
+
def to_binary
|
39
|
+
@@genes.collect {|gene, range|
|
40
|
+
output = String.new
|
41
|
+
value = self.send(gene) - self.class.send("#{gene}_min")
|
42
|
+
difference = range.bits - value.bits
|
43
|
+
difference.times { output << "0" }
|
44
|
+
output << value.to_binary
|
45
|
+
}.join("")
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
# generic initialize from hash, called by the others
|
51
|
+
def initialize(hash)
|
52
|
+
puts hash
|
53
|
+
hash.each_pair do |gene, value|
|
54
|
+
instance_variable_set( "@#{gene}", value )
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# used internally by ::new_random, a la #initialize
|
59
|
+
def initialize_randomly(*args, &block)
|
60
|
+
params = Hash.new
|
61
|
+
@@genes.each_pair do |gene, range|
|
62
|
+
value = self.class.send("#{gene}_min") + rand(range)
|
63
|
+
params[gene] = value
|
64
|
+
end
|
65
|
+
initialize(params)
|
66
|
+
end
|
67
|
+
|
68
|
+
# used internally by ::new_from_binary, a la #initialize
|
69
|
+
def initialize_from_binary(binary)
|
70
|
+
hash = hash_from_binary(binary)
|
71
|
+
initialize(hash)
|
72
|
+
end
|
73
|
+
|
74
|
+
def hash_from_binary(binary)
|
75
|
+
params = Hash.new
|
76
|
+
start = 0
|
77
|
+
@@genes.each_pair do |gene, range|
|
78
|
+
binary_chunk = binary[start..(start = start + range.bits - 1)]
|
79
|
+
offset = binary_chunk.to_i(2)
|
80
|
+
value = self.class.send("#{gene}_min") + offset
|
81
|
+
start += 1
|
82
|
+
params[gene] = value
|
83
|
+
end
|
84
|
+
puts params
|
85
|
+
params
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module Jinni
|
2
|
+
class Creature
|
3
|
+
# genetic eigenclass methods
|
4
|
+
class << self
|
5
|
+
|
6
|
+
# use after calling all attr_genetics
|
7
|
+
def set_schema
|
8
|
+
total = @@genes.values.reduce( :+ )
|
9
|
+
@@schema_total = total
|
10
|
+
end
|
11
|
+
|
12
|
+
# to be used like `Klass.new()`
|
13
|
+
def random_new(*args, &block)
|
14
|
+
obj = allocate
|
15
|
+
obj.send(:initialize_randomly, *args, &block)
|
16
|
+
obj
|
17
|
+
end
|
18
|
+
|
19
|
+
# to be used by `cross`, `Klass.new_from_binary(binary_string)`
|
20
|
+
def new_from_binary(*args, &block)
|
21
|
+
obj = allocate
|
22
|
+
obj.send(:initialize_from_binary, *args, &block)
|
23
|
+
obj
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
# use like attr_accessor
|
28
|
+
def attr_genetic( gene, min, max )
|
29
|
+
range = max - min
|
30
|
+
|
31
|
+
@@genes[gene] = range
|
32
|
+
|
33
|
+
# getter
|
34
|
+
define_method(gene) do
|
35
|
+
instance_variable_get("@"+gene.to_s)
|
36
|
+
end
|
37
|
+
|
38
|
+
# setter
|
39
|
+
define_method("#{gene}=") do |value|
|
40
|
+
raise "trying to set #{gene} outside of range" unless (min..max).cover? value
|
41
|
+
instance_variable_set("@"+gene.to_s, value)
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
# Eigenclass methods for getting class genes
|
46
|
+
|
47
|
+
# range class variable, getter
|
48
|
+
self.class_variable_set("@@#{gene.to_s}_range", range)
|
49
|
+
define_singleton_method("#{gene.to_s}_range") do
|
50
|
+
self.class_variable_get("@@#{gene.to_s}_range")
|
51
|
+
end
|
52
|
+
|
53
|
+
# min class variable, getter
|
54
|
+
self.class_variable_set("@@#{gene.to_s}_min", min)
|
55
|
+
define_singleton_method("#{gene.to_s}_min") do
|
56
|
+
self.class_variable_get("@@#{gene.to_s}_min")
|
57
|
+
end
|
58
|
+
|
59
|
+
# max class variable, getter
|
60
|
+
self.class_variable_set("@@#{gene.to_s}_max", max)
|
61
|
+
define_singleton_method("#{gene.to_s}_max") do
|
62
|
+
self.class_variable_get("@@#{gene.to_s}_max")
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
data/lib/jinni.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'pry'
|
2
|
+
|
3
|
+
require 'jinni/version'
|
4
|
+
require 'jinni/creature'
|
5
|
+
require 'jinni/eigenclass'
|
6
|
+
require 'jinni/numeric'
|
7
|
+
|
8
|
+
|
9
|
+
|
10
|
+
|
11
|
+
|
12
|
+
class Fish < Jinni::Creature
|
13
|
+
attr_genetic :hunger, -10, 10
|
14
|
+
attr_genetic :speed, 1, 100
|
15
|
+
attr_genetic :size, 90, 100
|
16
|
+
attr_genetic :pointiness, 50, 100
|
17
|
+
|
18
|
+
set_schema
|
19
|
+
end
|
20
|
+
|
21
|
+
bill = Fish.random_new()
|
22
|
+
ted = Fish.random_new()
|
23
|
+
|
24
|
+
child = bill.cross(ted)
|
25
|
+
|
26
|
+
binding.pry
|
metadata
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: jinni
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Andrew Monks
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-04-17 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.9'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.9'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
description:
|
42
|
+
email:
|
43
|
+
- a@monks.co
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- ".gitignore"
|
49
|
+
- ".travis.yml"
|
50
|
+
- Gemfile
|
51
|
+
- README.md
|
52
|
+
- Rakefile
|
53
|
+
- bin/console
|
54
|
+
- bin/setup
|
55
|
+
- jinni.gemspec
|
56
|
+
- lib/jinni.rb
|
57
|
+
- lib/jinni/creature.rb
|
58
|
+
- lib/jinni/eigenclass.rb
|
59
|
+
- lib/jinni/numeric.rb
|
60
|
+
- lib/jinni/version.rb
|
61
|
+
homepage: http://github.com/amonks/jinni
|
62
|
+
licenses: []
|
63
|
+
metadata: {}
|
64
|
+
post_install_message:
|
65
|
+
rdoc_options: []
|
66
|
+
require_paths:
|
67
|
+
- lib
|
68
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: '0'
|
73
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
requirements: []
|
79
|
+
rubyforge_project:
|
80
|
+
rubygems_version: 2.2.2
|
81
|
+
signing_key:
|
82
|
+
specification_version: 4
|
83
|
+
summary: unconventional genetics, aggressively metaprogrammed [hideous code use at
|
84
|
+
your own risk]
|
85
|
+
test_files: []
|
86
|
+
has_rdoc:
|