kittyverse 0.4.4 → 0.4.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7a711c97165ef02f83cdbfacde634a013fced668
4
- data.tar.gz: 512645367b54692385916a9136d092893fc91cf9
3
+ metadata.gz: 7d79b58472f3570c946876bf0461bf53ff2ddd4b
4
+ data.tar.gz: b8d563f8322a7328a3107c728623e4e1566845f3
5
5
  SHA512:
6
- metadata.gz: f1d71bd728a0968cbd0ec5bc58196bd5d12658b3bdd26a1b047fe6c9419d14ccdc2119825835ff7b437f3724a586c7d247edb74db3fc098a7ce094e5b7b47920
7
- data.tar.gz: 3b5a4c57a2087d1853f164b0662247506f9726a97372315aeb8b5f266055324d812814b91485fce6fe2294b6a30c2121e952cd1ebb10eba97bcf8c6976522462
6
+ metadata.gz: 659f667449ad8de67dc8387dfc24367fc113713f25b111bce6ea3dde52154f0204e2124c7088b960e08c579fe7c846e2a5dd43618c2bb6cb716c101e63ed814b
7
+ data.tar.gz: da6a2ad87961a114488a11febe6963d8a71b06aa38face8aa68a2cc0e35a0ecd0eb55a0d4de4d26983c78ebcf67f52683ccb7516e3da09f9356b3f9c205e81f0
@@ -9,6 +9,8 @@ lib/kittyverse/api/versions.rb
9
9
  lib/kittyverse/cattributes.rb
10
10
  lib/kittyverse/config/colors.rb
11
11
  lib/kittyverse/config/fancies.rb
12
+ lib/kittyverse/gene.rb
13
+ lib/kittyverse/genome.rb
12
14
  lib/kittyverse/config/purrstiges.rb
13
15
  lib/kittyverse/config/traits.rb
14
16
  lib/kittyverse/config/traits_timeline.rb
@@ -38,6 +38,9 @@ require 'kittyverse/fancies'
38
38
  require 'kittyverse/api/client'
39
39
  require 'kittyverse/api/versions'
40
40
 
41
+ ## genes / genome
42
+ require 'kittyverse/gene'
43
+ require 'kittyverse/genome'
41
44
 
42
45
 
43
46
  # say hello
@@ -0,0 +1,55 @@
1
+ # encoding: utf-8
2
+
3
+
4
+ class Gene
5
+
6
+ ### todo/check:
7
+ ## find a better name for Slice(incl.4 genes)
8
+ ## e.g. GeneFour, Gene4, GeneGroup, GeneSlice,TraitGenes,... - why? why not?
9
+
10
+ class Slice ## Gene::Slice (nested class)
11
+
12
+ attr_reader :type # trait type (tt)
13
+ attr_reader :d, :r1, :r2, :r3
14
+ # d (dominant gene) -- todo/check: rename to just d instead of d0 - why? why not?
15
+ # r1 (1st order recessive gene)
16
+ # r2 (2nd order recessive gene)
17
+ # r3 (3rd order recessive gene)
18
+ alias_method :d0, :d # allow "classic" alias for d too
19
+
20
+ ## compat: add alias for ("new/modern") p, h1, h2, h3
21
+ ## p(rimary), h(idden) 1, h(idden) 2, h(idden) 3
22
+ alias_method :p, :d
23
+ alias_method :h1, :r1
24
+ alias_method :h2, :r2
25
+ alias_method :h3, :r3
26
+
27
+
28
+ def initialize( type, d, r1, r2, r3 )
29
+ @type = TraitType[type] ## lookup trait type by key (e.g. :body, :pattern, etc.)
30
+ @d = @type[d] ## lookup trait (from trait type) by kai code (e.g. "1", "a", etc.)
31
+ @r1 = @type[r1]
32
+ @r2 = @type[r2]
33
+ @r3 = @type[r3]
34
+ end
35
+
36
+ def [](index)
37
+ case index
38
+ when 0 then @d
39
+ when 1 then @r1
40
+ when 2 then @r2
41
+ when 3 then @r3
42
+ else nil ## return nil for unknown index for now (raise except - why? why not?)
43
+ end
44
+ end
45
+
46
+ def purebred?() @d == @r1 && @d == @r2 && @d == @r3; end
47
+ alias_method :pure?, :purebred?
48
+
49
+
50
+ def to_kai
51
+ @r3.kai + @r2.kai + @r1.kai + @d.kai
52
+ end ## return a string in kai/base32 notation
53
+
54
+ end # class Slice
55
+ end # class Gene
@@ -0,0 +1,236 @@
1
+ # encoding: utf-8
2
+
3
+
4
+ class Genome
5
+
6
+ def initialize( arg )
7
+ if arg.is_a? Integer ## use Integer (Fixnum+Bignum??) - why? why not?
8
+ num = arg
9
+ kai = Kai.encode( num )
10
+ else
11
+ if arg.downcase.start_with?( '0x' ) ## assume hexstring( base16 )
12
+ kai = Kai.encode( arg.to_i(16) )
13
+ else # else assume string in kai/base32 format
14
+ kai = arg
15
+ kai = kai.gsub( ' ', '' ) ## allow spaces (strip/remove)
16
+ end
17
+ end
18
+ ## puts "Genome.initialize #{kai}"
19
+
20
+ @kai = kai ## note: store/save kai without any spaces ("compact" format)
21
+ @genes = build_genes( kai ) ## array of (sliced) genes (block of four genes)
22
+ end
23
+
24
+
25
+ def kai() Kai.fmt( @kai ); end # return formatted in blocks of 4
26
+ def bytes() Kai.bytes( @kai ); end
27
+
28
+ def num() Kai.decode( @kai ); end
29
+ alias_method :to_i, :num
30
+
31
+ def electrologica() Electrologica.fmt( Electrologica.encode( num ) ); end # return formatted in electrologica base32 format
32
+ alias_method :codes, :electrologica
33
+
34
+ def binary
35
+ @kai.chars.each_slice(4).map do |slice|
36
+ buf = ""
37
+ buf << Kai::BINARY[slice[0]]
38
+ buf << "-"
39
+ buf << Kai::BINARY[slice[1]]
40
+ buf << "-"
41
+ buf << Kai::BINARY[slice[2]]
42
+ buf << "-"
43
+ buf << Kai::BINARY[slice[3]]
44
+ buf
45
+ end.join( " " )
46
+ end
47
+ alias_method :bin, :binary
48
+
49
+
50
+ def build_genes( kai )
51
+ kai = kai.reverse ## note: reserve for easy left-to-right access
52
+ genes = [] ## array of (sliced) genes (block of four genes)
53
+ ## fix/todo: use as_json for "official" api order
54
+ ## note: use insert order from "official" api
55
+
56
+ ## genes << Gene::Slice.new( :body, kai[0],
57
+ ## kai[1],
58
+ ## kai[2],
59
+ ## kai[3] )
60
+ ## genes << Gene::Slice.new( :pattern, kai[4+0],
61
+ ## kai[4+1],
62
+ ## kai[4+2],
63
+ ## kai[4+3]] )
64
+
65
+ keys.each_with_index do |key,i|
66
+ genes << Gene::Slice.new( key, kai[4*i+0],
67
+ kai[4*i+1],
68
+ kai[4*i+2],
69
+ kai[4*i+3])
70
+ end
71
+ genes
72
+ end
73
+
74
+
75
+ def body() @genes[0]; end ## Fur (FU)
76
+ def pattern() @genes[1]; end ## Pattern (PA)
77
+ def coloreyes() @genes[2]; end ## Eyes Color (EC)
78
+ def eyes() @genes[3]; end ## Eyes Shape (ES)
79
+ def colorprimary() @genes[4]; end ## Base Color (BC)
80
+ def colorsecondary() @genes[5]; end ## Highlight Color (HC)
81
+ def colortertiary() @genes[6]; end ## Accent Color (AC)
82
+ def wild() @genes[7]; end ## Wild Element (WE)
83
+ def mouth() @genes[8]; end ## Mouth (MO)
84
+ def environment() @genes[9]; end ## Environment (EN)
85
+ def secret() @genes[10]; end ## Secret (SE)
86
+ def prestige() @genes[11]; end ## Purrstige (PU)
87
+
88
+ alias_method :color1, :colorprimary
89
+ alias_method :color2, :colorsecondary
90
+ alias_method :color3, :colortertiary
91
+ ## todo: add more alias(es) - why? why not?
92
+
93
+ ## add (convenience) alias for two-letter (trait type) codes too
94
+ alias_method :fu, :body
95
+ alias_method :pa, :pattern
96
+ alias_method :ec, :coloreyes
97
+ alias_method :es, :eyes
98
+ alias_method :bc, :colorprimary
99
+ alias_method :hc, :colorsecondary
100
+ alias_method :ac, :colortertiary
101
+ alias_method :we, :wild
102
+ alias_method :mo, :mouth
103
+ alias_method :en, :environment
104
+ alias_method :se, :secret
105
+ alias_method :pu, :prestige
106
+
107
+
108
+ def each() @genes.each { |slice| yield(slice) }; end
109
+ def each_with_index() @genes.each_with_index { |slice,i| yield(slice,i) }; end
110
+ alias_method :each_slice, :each
111
+ alias_method :each_slice_with_index, :each_with_index
112
+
113
+ def each_gene
114
+ @genes.each do |slice|
115
+ yield(slice.p)
116
+ yield(slice.r1)
117
+ yield(slice.r2)
118
+ yield(slice.r3)
119
+ end
120
+ end
121
+ def each_gene_with_index
122
+ @genes.each_with_index do |slice,i|
123
+ yield(slice.p, 4*i+0)
124
+ yield(slice.r1, 4*i+1)
125
+ yield(slice.r2, 4*i+2)
126
+ yield(slice.r3, 4*i+3)
127
+ end
128
+ end
129
+
130
+ def keys ## rename to trait_type_keys - why? why not?
131
+ [:body, ### todo/fix: use TRAITS.keys or something - why? why not?
132
+ :pattern,
133
+ :coloreyes,
134
+ :eyes,
135
+ :colorprimary,
136
+ :colorsecondary,
137
+ :colortertiary,
138
+ :wild,
139
+ :mouth,
140
+ :environment,
141
+ :secret,
142
+ :prestige]
143
+ end
144
+
145
+ def index( key )
146
+ if key.size == 2 && key =~ /^[A-Za-z]{2}$/ ## check for codes e.g. FU, PA, ... (or fu, pa,...)
147
+ key = key.upcase.to_sym
148
+ @@codes_by_index ||= %w(FU PA EC ES BC HC AC WE MO EN SE PU)
149
+ .each_with_index.reduce({}) do |h,(code,i)|
150
+ h[code.to_sym]=i; h
151
+ end
152
+ @@codes_by_index[ key ]
153
+ else
154
+ key = key.downcase.to_sym
155
+ key = ALT_TRAIT_TYPE_KEYS[ key ] if ALT_TRAIT_TYPE_KEYS[ key ]
156
+
157
+ @@keys_by_index ||= keys.each_with_index.reduce({}) do |h,(key,i)|
158
+ h[key]=i; h
159
+ end
160
+ @@keys_by_index[ key ]
161
+ end
162
+ end
163
+
164
+
165
+ def [](key)
166
+ if key.is_a? Integer ## assume 0,1,2,3,.. index
167
+ q , r = key.divmod(4) ## q=quotient, r=rest/modulus
168
+ ## e.g. 3.divmod(4) => [0,3]
169
+ ## 4.divmod(4) => [1,0]
170
+ ## 5.divmod(4) => [1,1] etc.
171
+ @genes[q][r]
172
+ else ## assume trait type key / symbol
173
+ @genes[index(key)]
174
+ end
175
+ end
176
+
177
+
178
+ def build_tables() GenomeTables.new( self ).build; end
179
+ end # class Genome
180
+
181
+
182
+
183
+
184
+ class GenomeTables
185
+ def initialize( genome )
186
+ @genome = genome
187
+ end
188
+
189
+ def build
190
+ pos = 0
191
+ buf = ""
192
+ buf << "Genes (256-Bit Integer Number):\n"
193
+ buf << "- Base 10 (Decimal): #{@genome.num}\n"
194
+ buf << "- Base 2 (Binary): #{@genome.binary}\n"
195
+ buf << "- Base 2⁵ = 32\n"
196
+ buf << " - (Kai): #{@genome.kai}\n"
197
+ buf << " - (Codes): #{@genome.codes}\n"
198
+ buf << "\n\n"
199
+
200
+ @genome.each do |slice|
201
+ tt = slice.type
202
+
203
+ buf << "#{tt.name} (#{tt.code}) - Genes #{tt.genes}\n\n"
204
+
205
+ ###
206
+ ## fix/todo: add stars for purity?
207
+ ## **** - all traits the same
208
+ ## *** - two same pairs of traits
209
+ ## ** - one pair of same traits
210
+
211
+ buf << "|Gene |Binary |Kai |Code | Name | |\n"
212
+ buf << "|------|---------|-----|-----|----------|---|\n"
213
+ buf << "| #{pos} | #{slice.d.binary} | #{slice.d.kai} | #{slice.d.code} |**#{fmt_trait(slice.d)}** | d |\n"; pos+=1
214
+ buf << "| #{pos} | #{slice.r1.binary} | #{slice.r1.kai} | #{slice.r1.code} |#{fmt_trait(slice.r1)} | r1 |\n"; pos+=1
215
+ buf << "| #{pos} | #{slice.r2.binary} | #{slice.r2.kai} | #{slice.r2.code} |#{fmt_trait(slice.r2)} | r2 |\n"; pos+=1
216
+ buf << "| #{pos} | #{slice.r3.binary} | #{slice.r3.kai} | #{slice.r3.code} |#{fmt_trait(slice.r3)} | r3 |\n"; pos+=1
217
+ buf << "\n"
218
+
219
+ if tt.key == :body ## add legend for first entry
220
+ buf << "d = dominant, r1 = 1st order recessive, r2 = 2nd order recessive, r3 = 3rd order recessive\n\n"
221
+ end
222
+ end
223
+
224
+ buf
225
+ end
226
+
227
+ ####################
228
+ ## helpers
229
+
230
+ def fmt_trait( trait )
231
+ buf = ""
232
+ buf << (trait.name || '∅')
233
+ buf << " #{trait.tier_roman}" if trait.tier > 0
234
+ buf
235
+ end
236
+ end # class GenomeTables
@@ -5,7 +5,7 @@ class Kittyverse
5
5
 
6
6
  MAJOR = 0
7
7
  MINOR = 4
8
- PATCH = 4
8
+ PATCH = 5
9
9
  VERSION = [MAJOR,MINOR,PATCH].join('.')
10
10
 
11
11
  def self.version
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kittyverse
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.4
4
+ version: 0.4.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gerald Bauer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-05-19 00:00:00.000000000 Z
11
+ date: 2019-05-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: base32-alphabets
@@ -78,6 +78,8 @@ files:
78
78
  - lib/kittyverse/config/traits.rb
79
79
  - lib/kittyverse/config/traits_timeline.rb
80
80
  - lib/kittyverse/fancies.rb
81
+ - lib/kittyverse/gene.rb
82
+ - lib/kittyverse/genome.rb
81
83
  - lib/kittyverse/links.rb
82
84
  - lib/kittyverse/mewtations.rb
83
85
  - lib/kittyverse/pages/genes.rb