-
Notifications
You must be signed in to change notification settings - Fork 3
/
generate_meta.rb
447 lines (391 loc) · 11.4 KB
/
generate_meta.rb
1
2
3
4
5
6
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
## add some core ext helpers
class Array
def excluding(*elements) self - elements.flatten; end
end
CATEGORIES = {
'base' => [
['dark small', 'medium small', 'light small', 'albino small'],
'brown',
['gray small','gray'],
['green small', 'green'],
'pink small', ## skip pink - always use small version for barbie
['purple small','purple'],
['red', 'white'], ## alternate red white
## classic specials
'alien',
'boned',
'bot',
'deathbot',
'demon',
'golden',
'hyena',
'mempool',
['pepe', 'pepe', 'pepe', 'pepe', 'pepe block'],
'rainbow',
'safemode',
'zombie',
## more
['blue orc', 'blue orc', 'blue'],
['greener orc', 'greener orc', 'greener'],
['orange orc', 'orange orc', 'orange', 'orange2 orc', 'orange2 orc', 'orange2'],
['gold orc', 'gold orc', 'gold'],
'black',
'default',
['maxibiz', 'maxibiz2', 'maxibiz3', 'maxibiz4',
'maxibiz5',
'maxibiz6',
# 'maxibiz punk', - no maxibiz punks for now
# 'maxibiz punk2',
## more ultra-rare 1/1s
'punk', 'squiggle'],
],
## use for maxibiz/black/default
'hair_black' => [
'mohawk', 'mohawk2',
'peakspike',
'bob', ## exclusive
],
'hair' => [
'mohawk',
'mohawk blonde',
'mohawk green',
'mohawk purple',
'mohawk red',
'mohawk2',
'mohawk2 blonde',
'mohawk2 green',
'mohawk2 purple',
'mohawk2 red',
'mohawk2 orange',
'mohawk2 pink',
'peakspike',
'peakspike purple',
'peakspike red',
# 'peakspike blonde',
],
## use for pink (barbie)
'hair_blonde_f' => [
'mohawk blonde', 'mohawk2 blonde',
'peakspike blonde', ## exclusive
'bob blonde small', ## exclusive
['bob blonde small', 'headband'], ## exclusive hair+hat combos
['bob blonde small', 'knittedcap'],
['bob blonde small', 'cap mcd red'],
['bob blonde small', 'frenchcap'],
],
'hat' => [
'bandana',
'bandana2',
'bowler',
'cap army',
'cap mcb',
'cap ordinal',
'cap safemode',
'cap terminal', 'cap terminal2',
'cap captain',
'cap',
'cowboyhat',
'crown',
'fez',
'flathat',
'knittedcap',
'knittedcap2',
'policecap',
'wizardhat',
'beanie',
'cap burgerking',
'cap mcd black',
'cap mcd red',
'cap mcd white',
'cap subway',
'jesterhat',
'helmet',
'helmet2',
'tophat',
'tophat midnight',
'wizardhat blue',
'wizardhat orange',
'wizardhat red',
'wizardhat dark',
'wizardhat gray',
'wizardhat midnight',
'wizardhat gold',
'wizardhat green',
'wizardhat white',
'headband',
],
'hoodies' => [
'hoodie',
'hoodie midnight',
'hoodie indigo',
'hoodie blue',
'hoodie cobalt',
'hoodie aqua',
'hoodie green',
'hoodie greener',
'hoodie limegreen',
'hoodie gold',
'hoodie orange',
'hoodie ruby',
'hoodie red',
'hoodie purple',
],
'hoodies_blonde_f' => [
'hoodie orange',
'hoodie pink', ## exclusive
],
'hat_blonde_f' => [ ### no top hats, no headband - what else?
'bandana',
'bandana2',
'bowler',
'cap army',
'cap mcb',
'cap ordinal',
'cap safemode',
'cap terminal',
'cap terminal2',
'cap captain',
'cap',
'cowboyhat',
'crown',
'fez',
'knittedcap',
'knittedcap2',
'policecap',
'wizardhat',
'beanie',
'cap burgerking',
'cap mcd black',
'cap mcd red',
'cap mcd white',
'cap subway',
'jesterhat',
'helmet',
'helmet2',
'wizardhat blue',
'wizardhat orange',
'wizardhat red',
'wizardhat dark',
'wizardhat gray',
'wizardhat midnight',
'wizardhat gold',
'wizardhat green',
'wizardhat white',
'frenchcap', ## exclusive
],
'lasereyes_black' => [
'maxibiz lasereyes blue',
'maxibiz lasereyes green',
'maxibiz lasereyes red',
'maxibiz lasereyes2 blue',
'maxibiz lasereyes2 green',
'maxibiz lasereyes2 red',
],
'lasereyes' => [
'lasereyes red',
'lasereyes green',
'lasereyes gold',
],
'lasereyes_blonde_f' => [
'lasereyes blue', # exclusive
],
'eyes' => [
'3d glasses',
'shades blend',
'shades rainbow',
'shades polarized',
'shades cool', ## exclusive (to non-blondes)
'eyepatch',
'eyes big',
'eyes bored',
'eyes bot',
'eyes bot green',
'eyes deathbot',
'eyes monobrow',
'eyes pepe',
'eyes right',
'eyes zombie',
'eyemask',
'vr',
],
'eyes_blonde_f' => [
'3d glasses',
'shades blend',
'shades rainbow',
'shades polarized',
'eyepatch',
'eyes big blue',
'eyes bot',
'eyes deathbot',
# 'eyes bored',
# 'eyes monobrow',
# 'eyemask',
'vr',
],
'more' => [
'earring', ## make earrings 3x
'earring cross',
'earring',
'earring cross',
'earring',
'earring cross',
'halo',
'bubblegum',
],
}
pp CATEGORIES
def random_attributes( base )
attributes = []
style = if ['black', 'default' ].include?( base ) || base.index( 'maxibiz' ) ## maxibiz/black/default
:black
elsif ['pink small'].include?( base ) ## pink (barbie)
:blonde
elsif ['squiggle'].include?( base )
:squiggle ## squiggle 1/1
elsif ['punk'].include?( base )
:punk ## golden punk 1/1
else ## "standard" humans incl. orc
:default
end
hair_attributes = case style
when :black then CATEGORIES['hair_black']
when :blonde then CATEGORIES['hair_blonde_f']
when :squiggle then nil # no hair
else CATEGORIES['hair']
end
hat_attributes = case style
when :blonde then CATEGORIES['hat_blonde_f'] + CATEGORIES['hoodies_blonde_f']
when :squiggle then nil # not hat (+ hoodies)
else CATEGORIES['hat'] + CATEGORIES['hoodies']
end
eyes_attributes = case style
when :black then CATEGORIES['eyes']+CATEGORIES['lasereyes_black']
when :blonde then CATEGORIES['eyes_blonde_f']+CATEGORIES['lasereyes_blonde_f']
when :punk then CATEGORIES['eyes'].excluding( 'eyepatch' ) + ['lasereyes-punk','lasereyes-punk','lasereyes-punk','lasereyes-punk','lasereyes-punk']
when :squiggle then CATEGORIES['eyes'].excluding( 'eyepatch' )
else CATEGORIES['eyes']+CATEGORIES['lasereyes']
end
more_attributes = case style
when :squiggle then nil
else CATEGORIES['more']
end
## 0,1 - hair (20%)
## 2,3,4,5,6,7,8 - hat (70%)
## 9 -none (10%)
hair_dist, hat_dist = case style
when :blonde then [[0,1,2,3,4], [5,6,7,8],] # more hair
else [[0,1],[2,3,4,5,6,7,8],] # more hats
end
hair_or_hat = rand( 10 )
if hair_dist.include?( hair_or_hat ) && hair_attributes
attributes << hair_attributes[ rand( hair_attributes.size ) ]
elsif hat_dist.include?( hair_or_hat ) && hat_attributes
attributes << hat_attributes[ rand( hat_attributes.size ) ]
else
## none; continue
end
if more_attributes
more = rand( 100 )
more_dist = style == :blonde ? [0,1,2,3,4,5,6,7,8,9] : [0] # 9% or 1%
if more_dist.include?( more )
attributes << more_attributes[ rand( more_attributes.size ) ]
else
## none; continue
end
end
## 70% if hair or hat
## 90% if no hair or hat
eyes = rand( 10 )
eyes_dist = hair_or_hat == 9 ? [0,1,2,3,4,5,6,7,8] : [0,1,2,3,4,5,6]
if eyes_dist.include?( eyes ) || [:punk, :squiggle].include?( style ) ## punk & squiggle always get eyes
attributes << eyes_attributes[ rand( eyes_attributes.size ) ]
else
## none; continue
end
## note: might included nested attributes (combos) - flatten
attributes.flatten
end
def generate_meta( max=1000, seed: 4242 )
srand( seed ) ## make deterministic
recs = []
backgrounds = [
'bitcoin pattern',
'red',
'green',
'dollar pattern',
'blue',
'euro pattern',
'aqua',
'classic',
'rainbow',
'ukraine',
'usa',
'china',
'great britain',
'europe',
'austria',
]
bases = CATEGORIES['base']
## track uniques (that is, duplicates)
uniques = Hash.new(0)
id = 0
loop do
base_candidates = bases[ id % bases.size ]
base = base_candidates.is_a?( Array ) ? base_candidates[ rand( base_candidates.size) ] : base_candidates
accessories = random_attributes( base )
bg = if base.index( 'default' )
'default' ### bg default exclusive for default
elsif base.index( 'maxibiz' )
'bitcoin orange'
elsif base.index( 'greener' )
'dollar pattern'
elsif base.index( 'blue' )
'euro pattern'
elsif base.index( 'orange' )
'bitcoin pattern'
elsif base.index( 'gold' ) && !base.index( 'golden')
'yellow' ## bg yellow exclusive for gold
else
backgrounds[id % backgrounds.size ]
end
attributes = [bg, base] + accessories
print "==> #{id}: "
pp attributes
## downcase and remove non alphnum - to normalize key (names)
key = attributes.map { |attr| attr.downcase.gsub( /[^a-z0-9]/, '') }.join('+')
if uniques.has_key?( key )
puts "!! WARN - duplicate: #{attributes.inspect}; retry"
uniques[ key ] += 1
next
else
uniques[ key ] += 1
end
rec = []
rec << id.to_s ## add id - starting at one
rec << base
rec << accessories.join(' / ')
rec << bg
recs << rec
id += 1
break if id >= max
end
##
# dump duplicates for stats
puts "duplicates:"
uniques.each do |key,count|
puts " #{count} - #{key}" if count > 1
end
recs
end
recs = generate_meta( 21000 )
## pp recs
headers = ['id', 'type', 'accessories', 'background']
File.open( "./monkesee-monkedo.csv", "w:utf-8" ) do |f|
f.write( headers.join( ', '))
f.write( "\n")
recs.each do |values|
f.write( values.join( ', ' ))
f.write( "\n" )
end
end
puts "bye"