copycats 0.0.1 → 0.5.0

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,45 @@
1
+ # encoding: utf-8
2
+
3
+ class KittyReport
4
+
5
+ def initialize( *args, **kwargs )
6
+ if args.empty? # try keyword args
7
+ @id = kwargs[:id]
8
+ @kai = kwargs[:genes] ## todo/check: also incl. check for kai key - why? why not?
9
+ else
10
+ # try positional args
11
+ ## for now alsways assume ActiveRecord - Kitty::Model
12
+ kitty = args[0]
13
+ @id = kitty.id
14
+ @kai = fmt_kai( kitty.genes ) ## pretty print in groups of four (4)
15
+ end
16
+ end
17
+
18
+ def build
19
+ buf = "# Kitty \##{@id}\n\n"
20
+ buf << "genes (kai): #{@kai}\n\n"
21
+ buf << Genome.new( @kai ).build_tables
22
+
23
+ ## puts buf
24
+
25
+ buf
26
+ end
27
+
28
+ def save( path )
29
+ File.open( path, "w" ) do |f|
30
+ f.write build
31
+ end
32
+ end
33
+
34
+
35
+ #####
36
+ # helpers
37
+ def fmt_kai( kai )
38
+ ## format in groups of four (4) separated by space
39
+ ## e.g. ccac7787fa7fafaa16467755f9ee444467667366cccceede
40
+ ## : ccac 7787 fa7f afaa 1646 7755 f9ee 4444 6766 7366 cccc eede
41
+ kai.reverse.gsub( /(.{4})/, '\1 ').reverse.strip
42
+ end
43
+
44
+
45
+ end # class KittyReport
@@ -0,0 +1,45 @@
1
+ # encoding: utf-8
2
+
3
+ class MixReport
4
+
5
+ def initialize( matron, sire )
6
+ @matron_id = matron.id
7
+ @sire_id = sire.id
8
+ @matron_kai = fmt_kai( matron.genes ) ## pretty print in groups of four (4)
9
+ @sire_kai = fmt_kai( sire.genes )
10
+ end
11
+
12
+
13
+ def build
14
+ buf = "# Kitty \##{@matron_id} + \##{@sire_id}\n\n"
15
+ buf << "genes (kai) 1: #{@matron_kai}\n"
16
+ buf << "genes (kai) 2: #{@sire_kai}\n\n"
17
+
18
+ buf << Genome.new( @matron_kai ).build_mix_tables( Genome.new( @sire_kai ))
19
+
20
+ ## puts buf
21
+ buf
22
+ end
23
+
24
+
25
+ ## fix/todo: use "generic" report class (inherits save)!!!!!
26
+ def save( path )
27
+ File.open( path, "w" ) do |f|
28
+ f.write build
29
+ end
30
+ end
31
+
32
+
33
+
34
+ #####
35
+ # helpers
36
+ # todo: move to helpers module for (re)use
37
+ def fmt_kai( kai )
38
+ ## format in groups of four (4) separated by space
39
+ ## e.g. ccac7787fa7fafaa16467755f9ee444467667366cccceede
40
+ ## : ccac 7787 fa7f afaa 1646 7755 f9ee 4444 6766 7366 cccc eede
41
+ kai.reverse.gsub( /(.{4})/, '\1 ').reverse.strip
42
+ end
43
+
44
+
45
+ end # class KittyReport
@@ -0,0 +1,122 @@
1
+ # encoding: utf-8
2
+
3
+ class TraitsReport
4
+
5
+ ROMAN = {
6
+ 1 => 'I',
7
+ 2 => 'II',
8
+ 3 => 'III',
9
+ 4 => 'IIII',
10
+ 5 => 'V'
11
+ }
12
+
13
+
14
+ def build
15
+ buf = ""
16
+ buf << "# Traits\n\n"
17
+
18
+ buf << "| Tier | Kai |"
19
+ TRAITS.values[0,6].each do |trait|
20
+ buf << " #{trait[:name]} |"
21
+ end
22
+ buf << "\n"
23
+ buf << "|----|----|----|----|----|----|----|----|\n"
24
+
25
+ buf << "| | |"
26
+ TRAITS.values[0,6].each do |trait|
27
+ buf << " #{trait[:genes]} |"
28
+ end
29
+ buf << "\n"
30
+
31
+ Kai::ALPHABET.each_char do |kai|
32
+ tier = ROMAN[ Kai::TIER[kai] ]
33
+ tier = '?' if tier.nil?
34
+ buf << "| #{tier} | #{kai} |"
35
+ TRAITS.values[0,6].each do |trait|
36
+ value = trait[:kai][kai]
37
+ value = '?' if value.nil? || value.empty?
38
+ buf << " #{value} |"
39
+ end
40
+ buf << "\n"
41
+ end
42
+ buf << "\n\n"
43
+
44
+ ## part ii (split into two tables)
45
+ buf << "| Tier | Kai |"
46
+ TRAITS.values[6,6].each do |trait|
47
+ buf << " #{trait[:name]} |"
48
+ end
49
+ buf << "\n"
50
+ buf << "|----|----|----|----|----|----|----|----|\n"
51
+
52
+ buf << "| | |"
53
+ TRAITS.values[6,6].each do |trait|
54
+ buf << " #{trait[:genes]} |"
55
+ end
56
+ buf << "\n"
57
+
58
+ Kai::ALPHABET.each_char do |kai|
59
+ tier = ROMAN[ Kai::TIER[kai] ]
60
+ tier = '?' if tier.nil?
61
+ buf << "| #{tier} | #{kai} |"
62
+ TRAITS.values[6,6].each do |trait|
63
+ value = trait[:kai][kai]
64
+ value = '?' if value.nil? || value.empty?
65
+ buf << " #{value} |"
66
+ end
67
+ buf << "\n"
68
+ end
69
+ buf << "\n\n"
70
+
71
+
72
+ buf += <<TXT
73
+ ## Mutations / Mewtations
74
+
75
+ 16 Mutation Pairs (16 x 2 = 32)
76
+
77
+ ```
78
+ Tier I Tier II Tier III Tier IIII Tier V
79
+ (1-g) (h-p) (q-t) (u,v) (w)
80
+ 1+2 = h h+i = q q+r = u u+v = w
81
+ 3+4 = i j+k = r s+t = v
82
+ 5+6 = j m+n = s
83
+ 7+8 = k o+p = t
84
+ 9+a = m
85
+ b+c = n
86
+ d+e = o
87
+ f+g = p
88
+ ```
89
+
90
+ Note: It's impossible for a mutation to reach `x` e.g. `w+x = x`.
91
+
92
+ ## Kai (Base32) Notation
93
+
94
+ |Kai |Binary |Num|Kai |Binary |Num|Kai |Binary |Num|Kai |Binary |Num|
95
+ |-------|-------|---|-------|-------|---|-------|-------|---|-------|-------|---|
96
+ | **1** | 00000 | 0 | **9** | 01000 | 8 | **h** | 10000 |16 | **q** | 11000 |24 |
97
+ | **2** | 00001 | 1 | **a** | 01001 | 9 | **i** | 10001 |17 | **r** | 11001 |25 |
98
+ | **3** | 00010 | 2 | **b** | 01010 | 10| **j** | 10010 |18 | **s** | 11010 |26 |
99
+ | **4** | 00011 | 3 | **c** | 01011 | 11| **k** | 10011 |19 | **t** | 11011 |27 |
100
+ | **5** | 00100 | 4 | **d** | 01100 | 12| **m** | 10100 |20 | **u** | 11100 |28 |
101
+ | **6** | 00101 | 5 | **e** | 01101 | 13| **n** | 10101 |21 | **v** | 11101 |29 |
102
+ | **7** | 00110 | 6 | **f** | 01110 | 14| **o** | 10110 |22 | **w** | 11110 |30 |
103
+ | **8** | 00111 | 7 | **g** | 01111 | 15| **p** | 10111 |23 | **x** | 11111 |31 |
104
+
105
+ Note: The digit-0 and the letter-l are NOT used in kai.
106
+
107
+ TXT
108
+
109
+
110
+ puts buf
111
+
112
+ buf
113
+ end ## method build
114
+
115
+
116
+ def save( path )
117
+ File.open( path, "w" ) do |f|
118
+ f.write build
119
+ end
120
+ end
121
+
122
+ end # class TraitsReport
@@ -0,0 +1,23 @@
1
+ # encoding: utf-8
2
+
3
+ class CreateDb
4
+
5
+ def up
6
+
7
+ ActiveRecord::Schema.define do
8
+
9
+ create_table :kitties do |t|
10
+ ### t.integer :ref, null: false ## reference id - todo - find a better name e.g. uid (for unique id?) or gid?
11
+ ## note: use built-in id for id!!!!
12
+
13
+ t.string :name ## optional name e.g. Genesis, Galaxy Cat, etc.
14
+ t.string :genes ## genes in kai format
15
+ t.integer :gen ## generation e.g. 0,1,2,etc.
16
+ end
17
+
18
+
19
+ end # block Schema.define
20
+
21
+ end # method up
22
+
23
+ end # class CreateDb
@@ -0,0 +1,66 @@
1
+ # encoding: utf-8
2
+
3
+ module Copycats
4
+
5
+ class Tool
6
+
7
+ def run( args )
8
+ opts = {}
9
+
10
+ parser = OptionParser.new do |cmd|
11
+ cmd.banner = "Usage: kitty [options]"
12
+
13
+ cmd.separator ""
14
+ cmd.separator " Data options:"
15
+
16
+ cmd.on("-i", "--include=DIR", "Data directory (default: ./data)") do |name|
17
+ opts[:data_dir] = name
18
+ end
19
+
20
+ cmd.separator ""
21
+ cmd.separator " General options:"
22
+
23
+ cmd.on("-h", "--help", "Prints this help") do
24
+ puts cmd
25
+ exit
26
+ end
27
+ end
28
+
29
+ parser.parse!( args )
30
+ pp opts
31
+
32
+
33
+ data_dir = opts[:data_dir] || './data'
34
+
35
+ setup( data_dir: data_dir )
36
+
37
+ pp args
38
+
39
+ if args.size == 1
40
+ id = args[0].to_i
41
+ kitty = Copycats::Model::Kitty.find( id )
42
+ ## pp k
43
+
44
+ buf = KittyReport.new( kitty ).build
45
+
46
+ puts buf
47
+ elsif args.size == 2
48
+ matron_id = args[0].to_i
49
+ sire_id = args[1].to_i
50
+
51
+ matron = Copycats::Model::Kitty.find( matron_id )
52
+ sire = Copycats::Model::Kitty.find( sire_id )
53
+ ## pp matron
54
+
55
+ buf = MixReport.new( matron, sire ).build
56
+
57
+ puts buf
58
+ else
59
+ puts "error: too many arguments (expected one or two kitty ids / names / genes)"
60
+ end
61
+ end ## method run
62
+
63
+
64
+ end ## class Tool
65
+
66
+ end ## module Copycats
@@ -0,0 +1,298 @@
1
+ # encoding: utf-8
2
+
3
+ ###
4
+ # trais / kaittributes
5
+ # see https://cryptokittydex.com/kaittributes
6
+ # https://docs.google.com/spreadsheets/d/1ShiBKSglFAB2vJe4Uow3iF09FBVq6ZAaOzTCIECf4iA
7
+ # http://www.rolldice.club/cryptokitties/wkt_tree.php
8
+ #
9
+
10
+
11
+
12
+ ## ordered by gene position (0,1,3.4,5,... etc.)
13
+ ## 12 traits (4 genes each)
14
+ TRAITS =
15
+ {
16
+ body: {
17
+ genes: '0-3',
18
+ name: 'Fur',
19
+ kai: {
20
+ '1' => 'savannah',
21
+ '2' => 'selkirk',
22
+ '3' => '',
23
+ '4' => 'birman',
24
+ '5' => '',
25
+ '6' => 'bobtail',
26
+ '7' => '',
27
+ '8' => '',
28
+ '9' => '',
29
+ 'a' => 'cymric',
30
+ 'b' => 'chartreux',
31
+ 'c' => 'himalayan',
32
+ 'd' => 'munchkin',
33
+ 'e' => 'sphynx',
34
+ 'f' => 'ragamuffin',
35
+ 'g' => 'ragdoll',
36
+ 'h' => 'norwegianforest',
37
+ 'i' => '',
38
+ 'j' => '',
39
+ 'k' => '',
40
+ 'm' => '',
41
+ 'n' => 'mainecoon',
42
+ 'o' => 'laperm',
43
+ 'p' => 'persian',
44
+ 'q' => '',
45
+ 'r' => '',
46
+ 's' => '',
47
+ 't' => 'manx',
48
+ 'u' => '',
49
+ 'v' => '',
50
+ 'w' => '',
51
+ 'x' => ''
52
+ }
53
+ },
54
+ pattern: {
55
+ genes: '4-7',
56
+ name: 'Pattern',
57
+ kai: {
58
+ '1' => '',
59
+ '2' => 'tiger',
60
+ '3' => '',
61
+ '4' => 'ganado',
62
+ '5' => 'leopard',
63
+ '6' => 'camo ',
64
+ '7' => '',
65
+ '8' => 'spangled',
66
+ '9' => 'calicool',
67
+ 'a' => 'luckystripe',
68
+ 'b' => 'amur',
69
+ 'c' => 'jaguar',
70
+ 'd' => 'spock',
71
+ 'e' => '',
72
+ 'f' => 'totesbasic', ## use totesbasic_f - why? why not?
73
+ 'g' => 'totesbasic', ## use totesbasic_g
74
+ 'h' => '',
75
+ 'i' => '',
76
+ 'j' => 'dippedcone',
77
+ 'k' => '',
78
+ 'm' => 'tigerpunk',
79
+ 'n' => 'henna',
80
+ 'o' => '',
81
+ 'p' => 'totesbasic', ## use totesbasic_p
82
+ 'q' => '',
83
+ 'r' => '',
84
+ 's' => 'hotrod',
85
+ 't' => '',
86
+ 'u' => '',
87
+ 'v' => '',
88
+ 'w' => '',
89
+ 'x' => ''
90
+ }
91
+ },
92
+ coloreyes: {
93
+ genes: '8-11',
94
+ name: 'Eye Color',
95
+ kai: {
96
+ '1' => 'thundergrey',
97
+ '2' => 'gold',
98
+ '3' => 'topaz',
99
+ '4' => 'mintgreen',
100
+ '5' => '',
101
+ '6' => 'sizzurp',
102
+ '7' => 'chestnut',
103
+ '8' => 'strawberry',
104
+ '9' => 'sapphire',
105
+ 'a' => 'forgetmenot',
106
+ 'b' => '',
107
+ 'c' => 'coralsunrise',
108
+ 'd' => '',
109
+ 'e' => '',
110
+ 'f' => '',
111
+ 'g' => '',
112
+ 'h' => 'pumpkin',
113
+ 'i' => 'limegreen',
114
+ 'j' => '',
115
+ 'k' => 'bubblegum',
116
+ 'm' => 'twilightsparkle',
117
+ 'n' => '',
118
+ 'o' => '',
119
+ 'p' => '',
120
+ 'q' => 'babypuke',
121
+ 'r' => '',
122
+ 's' => '',
123
+ 't' => '',
124
+ 'u' => '',
125
+ 'v' => '',
126
+ 'w' => '',
127
+ 'x' => ''
128
+ }
129
+ },
130
+ eyes: {
131
+ genes: '12-15',
132
+ name: 'Eye Shape', ## eye type
133
+ kai: {
134
+ '2' => 'wonky',
135
+ '3' => 'serpent',
136
+ '4' => 'googly',
137
+ '5' => 'otaku',
138
+ '6' => 'simple',
139
+ '7' => 'crazy',
140
+ '8' => 'thicccbrowz',
141
+ 'b' => 'baddate',
142
+ 'd' => 'chronic',
143
+ 'e' => 'slyboots',
144
+ 'f' => 'wiley',
145
+ 'g' => 'stunned',
146
+ 'i' => 'alien',
147
+ 'j' => 'fabulous',
148
+ 'k' => 'raisedbrow',
149
+ 'o' => 'sass',
150
+ 'p' => 'sweetmeloncakes',
151
+ 'r' => 'wingtips',
152
+ 't' => 'buzzed'
153
+ }
154
+ },
155
+ color1: {
156
+ genes: '16-19',
157
+ name: 'Base Color', ## colorprimary / body color
158
+ kai: {
159
+ '1' => 'shadowgrey',
160
+ '2' => 'salmon',
161
+ '4' => 'orangesoda',
162
+ '5' => 'cottoncandy',
163
+ '6' => 'mauveover',
164
+ '7' => 'aquamarine',
165
+ '8' => 'nachocheez',
166
+ '9' => 'harbourfog',
167
+ 'b' => 'greymatter',
168
+ 'f' => 'hintomint',
169
+ 'g' => 'bananacream',
170
+ 'h' => 'cloudwhite',
171
+ 'j' => 'oldlace',
172
+ 'k' => 'koala',
173
+ 'p' => 'verdigris',
174
+ 'r' => 'onyx'
175
+ }
176
+ },
177
+ color2: {
178
+ genes: '20-23',
179
+ name: 'Highlight Color', ## colorsecondary / sec color / pattern color
180
+ kai: {
181
+ '3' => 'egyptiankohl',
182
+ '5' => 'lilac',
183
+ '6' => 'apricot',
184
+ '7' => 'royalpurple',
185
+ '9' => 'swampgreen',
186
+ 'a' => 'violet',
187
+ 'b' => 'scarlet',
188
+ 'c' => 'barkbrown',
189
+ 'd' => 'coffee',
190
+ 'e' => 'lemonade',
191
+ 'f' => 'chocolate',
192
+ 'j' => 'turtleback',
193
+ 'm' => 'wolfgrey',
194
+ 'n' => 'cerulian',
195
+ 'o' => 'skyblue',
196
+ 's' => 'royalblue'
197
+ }
198
+ },
199
+ color3: {
200
+ genes: '24-27',
201
+ name: 'Accent Color', ## colortertiary
202
+ kai: {
203
+ '1' => 'belleblue',
204
+ '2' => 'sandalwood',
205
+ '3' => 'peach',
206
+ '4' => 'icy',
207
+ '5' => 'granitegrey',
208
+ '6' => '',
209
+ '7' => 'kittencream',
210
+ '8' => 'emeraldgreen',
211
+ '9' => '',
212
+ 'a' => '',
213
+ 'b' => 'purplehaze',
214
+ 'c' => '',
215
+ 'd' => 'azaleablush',
216
+ 'e' => 'missmuffett',
217
+ 'f' => 'morningglory',
218
+ 'g' => '',
219
+ 'h' => 'daffodil',
220
+ 'i' => 'flamingo',
221
+ 'j' => '',
222
+ 'k' => 'bloodred',
223
+ 'm' => '',
224
+ 'n' => '',
225
+ 'o' => 'periwinkle',
226
+ 'p' => '',
227
+ 'q' => 'seafoam',
228
+ 'r' => '',
229
+ 's' => '',
230
+ 't' => '',
231
+ 'u' => '',
232
+ 'v' => '',
233
+ 'w' => '',
234
+ 'x' => ''
235
+ }
236
+ },
237
+ wild: {
238
+ genes: '28-31',
239
+ name: 'Wild',
240
+ kai: {
241
+ 'i' => 'elk',
242
+ 'k' => 'trioculus'
243
+ }
244
+ },
245
+ mouth: {
246
+ genes: '32-35',
247
+ name: 'Mouth',
248
+ kai: {
249
+ '1' => 'whixtensions',
250
+ '2' => 'wasntme',
251
+ '3' => 'wuvme',
252
+ '4' => 'gerbil',
253
+ '5' => '',
254
+ '6' => '',
255
+ '7' => '',
256
+ '8' => '',
257
+ '9' => 'beard',
258
+ 'a' => 'pouty',
259
+ 'b' => 'saycheese',
260
+ 'c' => 'grim',
261
+ 'd' => '',
262
+ 'e' => '',
263
+ 'f' => 'happygokitty',
264
+ 'g' => 'soserious',
265
+ 'h' => 'cheeky',
266
+ 'i' => 'starstruck',
267
+ 'j' => '',
268
+ 'k' => '',
269
+ 'm' => 'dali',
270
+ 'n' => 'grimace',
271
+ 'o' => '',
272
+ 'p' => 'tongue',
273
+ 'q' => 'yokel',
274
+ 'r' => '',
275
+ 's' => 'neckbeard',
276
+ 't' => '',
277
+ 'u' => '',
278
+ 'v' => '',
279
+ 'w' => '',
280
+ 'x' => ''
281
+ }
282
+ },
283
+ future1: {
284
+ genes: '36-39',
285
+ name: 'Future 1',
286
+ kai: { } ## use alpha_1, alpha_2, ... - why? why not?
287
+ },
288
+ future2: {
289
+ genes: '40-43',
290
+ name: 'Future 2',
291
+ kai: { } ## use beta_1, beta_2, ... - why? why not?
292
+ },
293
+ future3: {
294
+ genes: '44-47',
295
+ name: 'Future 3',
296
+ kai: { } ## use gamma_1, gamma_2, ... - why? why not?
297
+ }
298
+ }