kittyverse 0.4.3 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CHANGELOG.md +3 -3
- data/Manifest.txt +5 -5
- data/README.md +416 -240
- data/Rakefile +30 -30
- data/lib/kittyverse.rb +39 -44
- data/lib/kittyverse/cattributes.rb +123 -131
- data/lib/kittyverse/config/colors.rb +146 -132
- data/lib/kittyverse/config/exclusives.rb +197 -0
- data/lib/kittyverse/config/fancies.rb +379 -174
- data/lib/kittyverse/config/purrstiges.rb +392 -200
- data/lib/kittyverse/config/special_editions.rb +135 -0
- data/lib/kittyverse/config/traits.rb +12 -0
- data/lib/kittyverse/config/traits_timeline.rb +288 -294
- data/lib/kittyverse/fancies.rb +206 -205
- data/lib/kittyverse/gene.rb +53 -0
- data/lib/kittyverse/genome.rb +176 -0
- data/lib/kittyverse/mewtations.rb +118 -120
- data/lib/kittyverse/recipes.rb +0 -2
- data/lib/kittyverse/traits.rb +0 -2
- data/lib/kittyverse/version.rb +20 -23
- data/test/helper.rb +10 -10
- data/test/test_cattributes.rb +0 -2
- data/test/test_fancies.rb +16 -2
- data/test/test_genome.rb +65 -0
- data/test/test_traits.rb +172 -174
- metadata +21 -17
- data/LICENSE.md +0 -116
- data/lib/kittyverse/api/client.rb +0 -149
- data/lib/kittyverse/api/versions.rb +0 -90
- data/lib/kittyverse/links.rb +0 -57
- data/lib/kittyverse/pages/genes.rb +0 -101
@@ -0,0 +1,176 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
class Genome
|
4
|
+
|
5
|
+
def initialize( arg )
|
6
|
+
if arg.is_a? Integer ## use Integer (Fixnum+Bignum??) - why? why not?
|
7
|
+
num = arg
|
8
|
+
kai = Kai.encode( num )
|
9
|
+
else
|
10
|
+
if arg.downcase.start_with?( '0x' ) ## assume hexstring( base16 )
|
11
|
+
kai = Kai.encode( arg.to_i(16) )
|
12
|
+
else # else assume string in kai/base32 format
|
13
|
+
kai = arg
|
14
|
+
kai = kai.gsub( ' ', '' ) ## allow spaces (strip/remove)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
## puts "Genome.initialize #{kai}"
|
18
|
+
|
19
|
+
@kai = kai ## note: store/save kai without any spaces ("compact" format)
|
20
|
+
@genes = build_genes( kai ) ## array of (sliced) genes (block of four genes)
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
def kai() Kai.fmt( @kai ); end # return formatted in blocks of 4
|
25
|
+
def bytes() Kai.bytes( @kai ); end
|
26
|
+
|
27
|
+
def num() Kai.decode( @kai ); end
|
28
|
+
alias_method :to_i, :num
|
29
|
+
|
30
|
+
def electrologica() Electrologica.fmt( Electrologica.encode( num ) ); end # return formatted in electrologica base32 format
|
31
|
+
alias_method :codes, :electrologica
|
32
|
+
|
33
|
+
def binary
|
34
|
+
@kai.chars.each_slice(4).map do |slice|
|
35
|
+
buf = ""
|
36
|
+
buf << Kai::BINARY[slice[0]]
|
37
|
+
buf << "-"
|
38
|
+
buf << Kai::BINARY[slice[1]]
|
39
|
+
buf << "-"
|
40
|
+
buf << Kai::BINARY[slice[2]]
|
41
|
+
buf << "-"
|
42
|
+
buf << Kai::BINARY[slice[3]]
|
43
|
+
buf
|
44
|
+
end.join( " " )
|
45
|
+
end
|
46
|
+
alias_method :bin, :binary
|
47
|
+
|
48
|
+
|
49
|
+
def build_genes( kai )
|
50
|
+
kai = kai.reverse ## note: reserve for easy left-to-right access
|
51
|
+
genes = [] ## array of (sliced) genes (block of four genes)
|
52
|
+
## fix/todo: use as_json for "official" api order
|
53
|
+
## note: use insert order from "official" api
|
54
|
+
|
55
|
+
## genes << Gene::Slice.new( :body, kai[0],
|
56
|
+
## kai[1],
|
57
|
+
## kai[2],
|
58
|
+
## kai[3] )
|
59
|
+
## genes << Gene::Slice.new( :pattern, kai[4+0],
|
60
|
+
## kai[4+1],
|
61
|
+
## kai[4+2],
|
62
|
+
## kai[4+3]] )
|
63
|
+
|
64
|
+
keys.each_with_index do |key,i|
|
65
|
+
genes << Gene::Slice.new( key, kai[4*i+0],
|
66
|
+
kai[4*i+1],
|
67
|
+
kai[4*i+2],
|
68
|
+
kai[4*i+3])
|
69
|
+
end
|
70
|
+
genes
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
def body() @genes[0]; end ## Fur (FU)
|
75
|
+
def pattern() @genes[1]; end ## Pattern (PA)
|
76
|
+
def coloreyes() @genes[2]; end ## Eyes Color (EC)
|
77
|
+
def eyes() @genes[3]; end ## Eyes Shape (ES)
|
78
|
+
def colorprimary() @genes[4]; end ## Base Color (BC)
|
79
|
+
def colorsecondary() @genes[5]; end ## Highlight Color (HC)
|
80
|
+
def colortertiary() @genes[6]; end ## Accent Color (AC)
|
81
|
+
def wild() @genes[7]; end ## Wild Element (WE)
|
82
|
+
def mouth() @genes[8]; end ## Mouth (MO)
|
83
|
+
def environment() @genes[9]; end ## Environment (EN)
|
84
|
+
def secret() @genes[10]; end ## Secret (SE)
|
85
|
+
def prestige() @genes[11]; end ## Purrstige (PU)
|
86
|
+
|
87
|
+
alias_method :color1, :colorprimary
|
88
|
+
alias_method :color2, :colorsecondary
|
89
|
+
alias_method :color3, :colortertiary
|
90
|
+
## todo: add more alias(es) - why? why not?
|
91
|
+
|
92
|
+
## add (convenience) alias for two-letter (trait type) codes too
|
93
|
+
alias_method :fu, :body
|
94
|
+
alias_method :pa, :pattern
|
95
|
+
alias_method :ec, :coloreyes
|
96
|
+
alias_method :es, :eyes
|
97
|
+
alias_method :bc, :colorprimary
|
98
|
+
alias_method :hc, :colorsecondary
|
99
|
+
alias_method :ac, :colortertiary
|
100
|
+
alias_method :we, :wild
|
101
|
+
alias_method :mo, :mouth
|
102
|
+
alias_method :en, :environment
|
103
|
+
alias_method :se, :secret
|
104
|
+
alias_method :pu, :prestige
|
105
|
+
|
106
|
+
|
107
|
+
def each() @genes.each { |slice| yield(slice) }; end
|
108
|
+
def each_with_index() @genes.each_with_index { |slice,i| yield(slice,i) }; end
|
109
|
+
alias_method :each_slice, :each
|
110
|
+
alias_method :each_slice_with_index, :each_with_index
|
111
|
+
|
112
|
+
def each_gene
|
113
|
+
@genes.each do |slice|
|
114
|
+
yield(slice.p)
|
115
|
+
yield(slice.r1)
|
116
|
+
yield(slice.r2)
|
117
|
+
yield(slice.r3)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
def each_gene_with_index
|
121
|
+
@genes.each_with_index do |slice,i|
|
122
|
+
yield(slice.p, 4*i+0)
|
123
|
+
yield(slice.r1, 4*i+1)
|
124
|
+
yield(slice.r2, 4*i+2)
|
125
|
+
yield(slice.r3, 4*i+3)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def keys ## rename to trait_type_keys - why? why not?
|
130
|
+
[:body, ### todo/fix: use TRAITS.keys or something - why? why not?
|
131
|
+
:pattern,
|
132
|
+
:coloreyes,
|
133
|
+
:eyes,
|
134
|
+
:colorprimary,
|
135
|
+
:colorsecondary,
|
136
|
+
:colortertiary,
|
137
|
+
:wild,
|
138
|
+
:mouth,
|
139
|
+
:environment,
|
140
|
+
:secret,
|
141
|
+
:prestige]
|
142
|
+
end
|
143
|
+
|
144
|
+
def index( key )
|
145
|
+
if key.size == 2 && key =~ /^[A-Za-z]{2}$/ ## check for codes e.g. FU, PA, ... (or fu, pa,...)
|
146
|
+
key = key.upcase.to_sym
|
147
|
+
@@codes_by_index ||= %w(FU PA EC ES BC HC AC WE MO EN SE PU)
|
148
|
+
.each_with_index.reduce({}) do |h,(code,i)|
|
149
|
+
h[code.to_sym]=i; h
|
150
|
+
end
|
151
|
+
@@codes_by_index[ key ]
|
152
|
+
else
|
153
|
+
key = key.downcase.to_sym
|
154
|
+
key = ALT_TRAIT_TYPE_KEYS[ key ] if ALT_TRAIT_TYPE_KEYS[ key ]
|
155
|
+
|
156
|
+
@@keys_by_index ||= keys.each_with_index.reduce({}) do |h,(key,i)|
|
157
|
+
h[key]=i; h
|
158
|
+
end
|
159
|
+
@@keys_by_index[ key ]
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
|
164
|
+
def [](key)
|
165
|
+
if key.is_a? Integer ## assume 0,1,2,3,.. index
|
166
|
+
q , r = key.divmod(4) ## q=quotient, r=rest/modulus
|
167
|
+
## e.g. 3.divmod(4) => [0,3]
|
168
|
+
## 4.divmod(4) => [1,0]
|
169
|
+
## 5.divmod(4) => [1,1] etc.
|
170
|
+
@genes[q][r]
|
171
|
+
else ## assume trait type key / symbol
|
172
|
+
@genes[index(key)]
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end # class Genome
|
176
|
+
|
@@ -1,120 +1,118 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
# Tier
|
5
|
-
# Tier
|
6
|
-
# Tier
|
7
|
-
#
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
'
|
13
|
-
'
|
14
|
-
'
|
15
|
-
'
|
16
|
-
'
|
17
|
-
'
|
18
|
-
'
|
19
|
-
'
|
20
|
-
'
|
21
|
-
'
|
22
|
-
'
|
23
|
-
'
|
24
|
-
'
|
25
|
-
'
|
26
|
-
'
|
27
|
-
'
|
28
|
-
'
|
29
|
-
'
|
30
|
-
'
|
31
|
-
'
|
32
|
-
'
|
33
|
-
'
|
34
|
-
'
|
35
|
-
'
|
36
|
-
'
|
37
|
-
'
|
38
|
-
'
|
39
|
-
'
|
40
|
-
'
|
41
|
-
'
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
'
|
49
|
-
'
|
50
|
-
'
|
51
|
-
'
|
52
|
-
'
|
53
|
-
'
|
54
|
-
'
|
55
|
-
'
|
56
|
-
'
|
57
|
-
'
|
58
|
-
'
|
59
|
-
'
|
60
|
-
'
|
61
|
-
'
|
62
|
-
'
|
63
|
-
'
|
64
|
-
'
|
65
|
-
'
|
66
|
-
'
|
67
|
-
'
|
68
|
-
'
|
69
|
-
'
|
70
|
-
'
|
71
|
-
'
|
72
|
-
'
|
73
|
-
'
|
74
|
-
'
|
75
|
-
'
|
76
|
-
'
|
77
|
-
'
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
'
|
84
|
-
'
|
85
|
-
'
|
86
|
-
'
|
87
|
-
'
|
88
|
-
'
|
89
|
-
'
|
90
|
-
'
|
91
|
-
'
|
92
|
-
'
|
93
|
-
'
|
94
|
-
'
|
95
|
-
'
|
96
|
-
'
|
97
|
-
'
|
98
|
-
'
|
99
|
-
'
|
100
|
-
'
|
101
|
-
'
|
102
|
-
'
|
103
|
-
'
|
104
|
-
'
|
105
|
-
'
|
106
|
-
'
|
107
|
-
'
|
108
|
-
'
|
109
|
-
'
|
110
|
-
'
|
111
|
-
'
|
112
|
-
'
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
MEWTATION_TIER_ROMAN = MUTATION_TIER_ROMAN
|
120
|
-
MEWTATION_PAIR = MUTATION_PAIR
|
1
|
+
##################################
|
2
|
+
# Tier 0 (Base) (1-g)
|
3
|
+
# Tier 1 (Mewtation I) (h-p)
|
4
|
+
# Tier 2 (Mewtation II) (q-t)
|
5
|
+
# Tier 3 (Mewtation III) (u,v)
|
6
|
+
# Tier 4 (Mewtation IIII) (w) # note: use IIII instead of IV
|
7
|
+
#
|
8
|
+
|
9
|
+
MUTATION_TIER = { ## todo/fix: use an algo to calculate - why? why not?
|
10
|
+
'1' => 0,
|
11
|
+
'2' => 0,
|
12
|
+
'3' => 0,
|
13
|
+
'4' => 0,
|
14
|
+
'5' => 0,
|
15
|
+
'6' => 0,
|
16
|
+
'7' => 0,
|
17
|
+
'8' => 0,
|
18
|
+
'9' => 0,
|
19
|
+
'a' => 0,
|
20
|
+
'b' => 0,
|
21
|
+
'c' => 0,
|
22
|
+
'd' => 0,
|
23
|
+
'e' => 0,
|
24
|
+
'f' => 0,
|
25
|
+
'g' => 0,
|
26
|
+
'h' => 1,
|
27
|
+
'i' => 1,
|
28
|
+
'j' => 1,
|
29
|
+
'k' => 1,
|
30
|
+
'm' => 1,
|
31
|
+
'n' => 1,
|
32
|
+
'o' => 1,
|
33
|
+
'p' => 1,
|
34
|
+
'q' => 2,
|
35
|
+
'r' => 2,
|
36
|
+
's' => 2,
|
37
|
+
't' => 2,
|
38
|
+
'u' => 3,
|
39
|
+
'v' => 3,
|
40
|
+
'w' => 4,
|
41
|
+
'x' => nil
|
42
|
+
}
|
43
|
+
|
44
|
+
## (quick 'n' dirty) kai to mutation/mewtation tier level in roman numerals (I,II,III,IIII) - as strings (and nil)
|
45
|
+
MUTATION_TIER_ROMAN = {
|
46
|
+
'1' => '',
|
47
|
+
'2' => '',
|
48
|
+
'3' => '',
|
49
|
+
'4' => '',
|
50
|
+
'5' => '',
|
51
|
+
'6' => '',
|
52
|
+
'7' => '',
|
53
|
+
'8' => '',
|
54
|
+
'9' => '',
|
55
|
+
'a' => '',
|
56
|
+
'b' => '',
|
57
|
+
'c' => '',
|
58
|
+
'd' => '',
|
59
|
+
'e' => '',
|
60
|
+
'f' => '',
|
61
|
+
'g' => '',
|
62
|
+
'h' => 'I',
|
63
|
+
'i' => 'I',
|
64
|
+
'j' => 'I',
|
65
|
+
'k' => 'I',
|
66
|
+
'm' => 'I',
|
67
|
+
'n' => 'I',
|
68
|
+
'o' => 'I',
|
69
|
+
'p' => 'I',
|
70
|
+
'q' => 'II',
|
71
|
+
'r' => 'II',
|
72
|
+
's' => 'II',
|
73
|
+
't' => 'II',
|
74
|
+
'u' => 'III',
|
75
|
+
'v' => 'III',
|
76
|
+
'w' => 'IIII',
|
77
|
+
'x' => '' ## Use nil and NOT empty string "" - why? why not?
|
78
|
+
}
|
79
|
+
|
80
|
+
MUTATION_PAIR = {
|
81
|
+
'1' => '', ## todo: use nil for "" - why? why not?
|
82
|
+
'2' => '',
|
83
|
+
'3' => '',
|
84
|
+
'4' => '',
|
85
|
+
'5' => '',
|
86
|
+
'6' => '',
|
87
|
+
'7' => '',
|
88
|
+
'8' => '',
|
89
|
+
'9' => '',
|
90
|
+
'a' => '',
|
91
|
+
'b' => '',
|
92
|
+
'c' => '',
|
93
|
+
'd' => '',
|
94
|
+
'e' => '',
|
95
|
+
'f' => '',
|
96
|
+
'g' => '',
|
97
|
+
'h' => '1+2',
|
98
|
+
'i' => '3+4',
|
99
|
+
'j' => '5+6',
|
100
|
+
'k' => '7+8',
|
101
|
+
'm' => '9+a',
|
102
|
+
'n' => 'b+c',
|
103
|
+
'o' => 'd+e',
|
104
|
+
'p' => 'f+g',
|
105
|
+
'q' => 'h+i',
|
106
|
+
'r' => 'j+k',
|
107
|
+
's' => 'm+n',
|
108
|
+
't' => 'o+p',
|
109
|
+
'u' => 'q+r',
|
110
|
+
'v' => 's+t',
|
111
|
+
'w' => 'u+v',
|
112
|
+
'x' => ''
|
113
|
+
}
|
114
|
+
|
115
|
+
## add alias(es)
|
116
|
+
MEWTATION_TIER = MUTATION_TIER
|
117
|
+
MEWTATION_TIER_ROMAN = MUTATION_TIER_ROMAN
|
118
|
+
MEWTATION_PAIR = MUTATION_PAIR
|
data/lib/kittyverse/recipes.rb
CHANGED
data/lib/kittyverse/traits.rb
CHANGED
data/lib/kittyverse/version.rb
CHANGED
@@ -1,23 +1,20 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
end
|
22
|
-
|
23
|
-
end # module Kittyverse
|
1
|
+
class Kittyverse
|
2
|
+
|
3
|
+
MAJOR = 1
|
4
|
+
MINOR = 0
|
5
|
+
PATCH = 1
|
6
|
+
VERSION = [MAJOR,MINOR,PATCH].join('.')
|
7
|
+
|
8
|
+
def self.version
|
9
|
+
VERSION
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.banner
|
13
|
+
"kittyverse/#{VERSION} on Ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}] in (#{root})"
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.root
|
17
|
+
File.expand_path( File.dirname(File.dirname(File.dirname(__FILE__))) )
|
18
|
+
end
|
19
|
+
|
20
|
+
end # module Kittyverse
|