cryptopunks 1.1.1 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Manifest.txt +5 -0
- data/README.md +106 -0
- data/config/spritesheet.csv +237 -0
- data/config/spritesheet.png +0 -0
- data/lib/cryptopunks/colors.rb +162 -0
- data/lib/cryptopunks/composite.rb +18 -48
- data/lib/cryptopunks/generator.rb +204 -0
- data/lib/cryptopunks/image.rb +33 -0
- data/lib/cryptopunks/structs.rb +19 -6
- data/lib/cryptopunks/version.rb +2 -2
- data/lib/cryptopunks.rb +71 -5
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b8706844322a9c1f651ec2dbe8d29d7a7ff7f3037c12683692b1e8b22c2e65d2
|
4
|
+
data.tar.gz: 350e1123a03bc107c8dde3ab596910201ae57471bc5e10a31025914d6cdf541d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2f801518afc9f8c85302d0986ac46541316d9fda6f309dafa1f200cc183a5fe648a31f46448ec59c9217d0c17d51f2f8abc1c6501814e447432ae4641f12d299
|
7
|
+
data.tar.gz: 70acc6c4b460cffe95f2647d9ecf6cf8d34b928bb9f6b02de27ed3fdb2cd15e180dd41be631ef66acdb2cda0ebe5bdbb13a7a5654fac3c56e1ab19aed94d6d8c
|
data/Manifest.txt
CHANGED
@@ -4,9 +4,14 @@ README.md
|
|
4
4
|
Rakefile
|
5
5
|
bin/cryptopunk
|
6
6
|
bin/punk
|
7
|
+
config/spritesheet.csv
|
8
|
+
config/spritesheet.png
|
7
9
|
lib/cryptopunks.rb
|
8
10
|
lib/cryptopunks/attributes.rb
|
11
|
+
lib/cryptopunks/colors.rb
|
9
12
|
lib/cryptopunks/composite.rb
|
10
13
|
lib/cryptopunks/dataset.rb
|
14
|
+
lib/cryptopunks/generator.rb
|
15
|
+
lib/cryptopunks/image.rb
|
11
16
|
lib/cryptopunks/structs.rb
|
12
17
|
lib/cryptopunks/version.rb
|
data/README.md
CHANGED
@@ -30,6 +30,7 @@ Usage: cryptopunk [options] IDs
|
|
30
30
|
-z, --zoom=ZOOM Zoom factor x2, x4, x8, etc. (default: 1)
|
31
31
|
-d, --dir=DIR Output directory (default: .)
|
32
32
|
-f, --file=FILE True Official Genuine CryptoPunks™ composite image (default: ./punks.png)
|
33
|
+
--offset=NUM Start counting at offset (default: 0)
|
33
34
|
-h, --help Prints this help
|
34
35
|
```
|
35
36
|
|
@@ -117,6 +118,111 @@ And x8:
|
|
117
118
|
And so on.
|
118
119
|
|
119
120
|
|
121
|
+
|
122
|
+
|
123
|
+
## 10 000 More Punks - Unauthorized? No Way?!- Fuck the Establishment - Yes, You Can - Do-It-Yourself - Use Your Own Collections
|
124
|
+
|
125
|
+
|
126
|
+
Use the `-f, --file=FILE` option
|
127
|
+
to pass along any unauthorized edition.
|
128
|
+
Only make sure all punks are lined-up left-to-right, top-to-bottom
|
129
|
+
in the 24x24 pixel format in the composite image.
|
130
|
+
|
131
|
+
|
132
|
+
Let's try the 10 000 More Punks series housing punks in
|
133
|
+
packs of a hundred each. Let's have a looksie at the first 100
|
134
|
+
in the series.
|
135
|
+
|
136
|
+
|
137
|
+
![](https://github.com/cryptopunksnotdead/awesome-cryptopunks-bubble/raw/master/i/more-punks-1.png)
|
138
|
+
|
139
|
+
|
140
|
+
|
141
|
+
Let's mint punk #0, #19, #50, and #89
|
142
|
+
and let's add an offset of 10000
|
143
|
+
(to start counting at 10000 instead of 0):
|
144
|
+
|
145
|
+
```
|
146
|
+
$ punk 0 18 40 88 --file ./more-punks-1.png --offset 10000
|
147
|
+
```
|
148
|
+
|
149
|
+
printing:
|
150
|
+
|
151
|
+
```
|
152
|
+
==> reading >./more-punks-1.png<...
|
153
|
+
240x240 (height x width)
|
154
|
+
==> (1/4) minting punk #10000; writing to >./punk-10000.png<...
|
155
|
+
==> (2/4) minting punk #10018; writing to >./punk-10018.png<...
|
156
|
+
==> (3/4) minting punk #10040; writing to >./punk-10040.png<...
|
157
|
+
==> (4/4) minting punk #10040; writing to >./punk-10088.png<...
|
158
|
+
```
|
159
|
+
|
160
|
+
And voila!
|
161
|
+
|
162
|
+
![](https://github.com/cryptopunksnotdead/cryptopunks/raw/master/cryptopunks/i/punk-10000.png)
|
163
|
+
![](https://github.com/cryptopunksnotdead/cryptopunks/raw/master/cryptopunks/i/punk-10018.png)
|
164
|
+
![](https://github.com/cryptopunksnotdead/cryptopunks/raw/master/cryptopunks/i/punk-10040.png)
|
165
|
+
![](https://github.com/cryptopunksnotdead/cryptopunks/raw/master/cryptopunks/i/punk-10088.png)
|
166
|
+
|
167
|
+
|
168
|
+
And 4x:
|
169
|
+
|
170
|
+
![](https://github.com/cryptopunksnotdead/cryptopunks/raw/master/cryptopunks/i/punk-10000x4.png)
|
171
|
+
![](https://github.com/cryptopunksnotdead/cryptopunks/raw/master/cryptopunks/i/punk-10018x4.png)
|
172
|
+
![](https://github.com/cryptopunksnotdead/cryptopunks/raw/master/cryptopunks/i/punk-10040x4.png)
|
173
|
+
![](https://github.com/cryptopunksnotdead/cryptopunks/raw/master/cryptopunks/i/punk-10088x4.png)
|
174
|
+
|
175
|
+
|
176
|
+
|
177
|
+
|
178
|
+
Let's try the second pack - that is, punks 100 to 199 in the series.
|
179
|
+
|
180
|
+
|
181
|
+
![](https://github.com/cryptopunksnotdead/awesome-cryptopunks-bubble/raw/master/i/more-punks-2.png)
|
182
|
+
|
183
|
+
|
184
|
+
|
185
|
+
Let's mint punk #0, #79, #80, and #90
|
186
|
+
and let's add an offset of 10100
|
187
|
+
(to start counting at 10000 plus 100 instead of 0):
|
188
|
+
|
189
|
+
```
|
190
|
+
$ punk 0 79 80 90 --file ./more-punks-2.png --offset 10100
|
191
|
+
```
|
192
|
+
|
193
|
+
printing:
|
194
|
+
|
195
|
+
```
|
196
|
+
==> reading >./more-punks-2.png<...
|
197
|
+
240x240 (height x width)
|
198
|
+
==> (1/4) minting punk #10100; writing to >./punk-10100.png<...
|
199
|
+
==> (2/4) minting punk #10179; writing to >./punk-10179.png<...
|
200
|
+
==> (3/4) minting punk #10180; writing to >./punk-10180.png<...
|
201
|
+
==> (4/4) minting punk #10190; writing to >./punk-10190.png<...
|
202
|
+
```
|
203
|
+
|
204
|
+
And voila! Super rare - world's first female alien and much more.
|
205
|
+
|
206
|
+
|
207
|
+
![](https://github.com/cryptopunksnotdead/cryptopunks/raw/master/cryptopunks/i/punk-10100.png)
|
208
|
+
![](https://github.com/cryptopunksnotdead/cryptopunks/raw/master/cryptopunks/i/punk-10179.png)
|
209
|
+
![](https://github.com/cryptopunksnotdead/cryptopunks/raw/master/cryptopunks/i/punk-10180.png)
|
210
|
+
![](https://github.com/cryptopunksnotdead/cryptopunks/raw/master/cryptopunks/i/punk-10190.png)
|
211
|
+
|
212
|
+
|
213
|
+
And 4x:
|
214
|
+
|
215
|
+
![](https://github.com/cryptopunksnotdead/cryptopunks/raw/master/cryptopunks/i/punk-10100x4.png)
|
216
|
+
![](https://github.com/cryptopunksnotdead/cryptopunks/raw/master/cryptopunks/i/punk-10179x4.png)
|
217
|
+
![](https://github.com/cryptopunksnotdead/cryptopunks/raw/master/cryptopunks/i/punk-10180x4.png)
|
218
|
+
![](https://github.com/cryptopunksnotdead/cryptopunks/raw/master/cryptopunks/i/punk-10190x4.png)
|
219
|
+
|
220
|
+
|
221
|
+
And so on.
|
222
|
+
|
223
|
+
|
224
|
+
|
225
|
+
|
120
226
|
## Usage in Your Scripts
|
121
227
|
|
122
228
|
|
@@ -0,0 +1,237 @@
|
|
1
|
+
id, name, gender, type, more_names
|
2
|
+
0, Male 1, m, Archetype - Human,
|
3
|
+
1, Male 2, m, Archetype - Human,
|
4
|
+
2, Male 3, m, Archetype - Human,
|
5
|
+
3, Male 4, m, Archetype - Human,
|
6
|
+
4, Female 1, f, Archetype - Human,
|
7
|
+
5, Female 2, f, Archetype - Human,
|
8
|
+
6, Female 3, f, Archetype - Human,
|
9
|
+
7, Female 4, f, Archetype - Human,
|
10
|
+
8, Zombie, m, Archetype - Zombie,
|
11
|
+
9, Zombie Female, f, Archetype - Zombie,
|
12
|
+
10, Ape, m, Archetype - Ape,
|
13
|
+
11, Ape Female, f, Archetype - Ape,
|
14
|
+
12, Alien, m, Archetype - Alien,
|
15
|
+
13, Alien Female, f, Archetype - Alien,
|
16
|
+
14, Demon, m, Archetype - Demon,
|
17
|
+
15, Demon Female, f, Archetype - Demon,
|
18
|
+
16, Mummy, m, Archetype - Mummy,
|
19
|
+
17, Mummy Female, f, Archetype - Mummy,
|
20
|
+
18, Orc, m, Archetype - Orc,
|
21
|
+
19, Orc Female, f, Archetype - Orc,
|
22
|
+
20, Robot, m, Archetype - Robot,
|
23
|
+
21, Robot Female, f, Archetype - Robot,
|
24
|
+
22, Skeleton, m, Archetype - Skeleton,
|
25
|
+
23, Skeleton Female, f, Archetype - Skeleton,
|
26
|
+
24, Vampire, m, Archetype - Vampire,
|
27
|
+
25, Vampire Female, f, Archetype - Vampire,
|
28
|
+
26, Zombie (Ape), m, Archetype - Zombie,
|
29
|
+
27, Alien (Ape), m, Archetype - Alien,
|
30
|
+
28, Alien 0°, m, Archetype - Alien,
|
31
|
+
29, Alien 30°, m, Archetype - Alien,
|
32
|
+
30, Alien 60°, m, Archetype - Alien,
|
33
|
+
31, Alien 90°, m, Archetype - Alien,
|
34
|
+
32, Alien 120°, m, Archetype - Alien,
|
35
|
+
33, Alien 150°, m, Archetype - Alien,
|
36
|
+
34, Alien 180°, m, Archetype - Alien,
|
37
|
+
35, Alien 210°, m, Archetype - Alien,
|
38
|
+
36, Alien 240°, m, Archetype - Alien,
|
39
|
+
37, Alien 270°, m, Archetype - Alien,
|
40
|
+
38, Alien 300°, m, Archetype - Alien,
|
41
|
+
39, Alien 330°, m, Archetype - Alien,
|
42
|
+
40, Alien (Ape) 0°, m, Archetype - Alien,
|
43
|
+
41, Alien (Ape) 30°, m, Archetype - Alien,
|
44
|
+
42, Alien (Ape) 60°, m, Archetype - Alien,
|
45
|
+
43, Alien (Ape) 90°, m, Archetype - Alien,
|
46
|
+
44, Alien (Ape) 120°, m, Archetype - Alien,
|
47
|
+
45, Alien (Ape) 150°, m, Archetype - Alien,
|
48
|
+
46, Alien (Ape) 180°, m, Archetype - Alien,
|
49
|
+
47, Alien (Ape) 210°, m, Archetype - Alien,
|
50
|
+
48, Alien (Ape) 240°, m, Archetype - Alien,
|
51
|
+
49, Alien (Ape) 270°, m, Archetype - Alien,
|
52
|
+
50, Alien (Ape) 300°, m, Archetype - Alien,
|
53
|
+
51, Alien (Ape) 330°, m, Archetype - Alien,
|
54
|
+
52, Alien Female 0°, f, Archetype - Alien,
|
55
|
+
53, Alien Female 30°, f, Archetype - Alien,
|
56
|
+
54, Alien Female 60°, f, Archetype - Alien,
|
57
|
+
55, Alien Female 90°, f, Archetype - Alien,
|
58
|
+
56, Alien Female 120°, f, Archetype - Alien,
|
59
|
+
57, Alien Female 150°, f, Archetype - Alien,
|
60
|
+
58, Alien Female 180°, f, Archetype - Alien,
|
61
|
+
59, Alien Female 210°, f, Archetype - Alien,
|
62
|
+
60, Alien Female 240°, f, Archetype - Alien,
|
63
|
+
61, Alien Female 270°, f, Archetype - Alien,
|
64
|
+
62, Alien Female 300°, f, Archetype - Alien,
|
65
|
+
63, Alien Female 330°, f, Archetype - Alien,
|
66
|
+
64, 3D Glasses, m, Attribute,
|
67
|
+
65, 3D Glasses, f, Attribute,
|
68
|
+
66, Bandana, m, Attribute,
|
69
|
+
67, Bandana, f, Attribute,
|
70
|
+
68, Beanie, m, Attribute,
|
71
|
+
69, Beanie, f, Attribute,
|
72
|
+
70, Big Beard, m, Attribute,
|
73
|
+
71, Big Shades, m, Attribute,
|
74
|
+
72, Big Shades, f, Attribute,
|
75
|
+
73, Black Lipstick, f, Attribute,
|
76
|
+
74, Blonde Bob, f, Attribute,
|
77
|
+
75, Blonde Short, f, Attribute,
|
78
|
+
76, Blue Eye Shadow, f, Attribute,
|
79
|
+
77, Buck Teeth, m, Attribute,
|
80
|
+
78, Cap, m, Attribute,
|
81
|
+
79, Cap, f, Attribute,
|
82
|
+
80, Cap Forward, m, Attribute,
|
83
|
+
81, Cap Forward, f, Attribute,
|
84
|
+
82, Chinstrap, m, Attribute,
|
85
|
+
83, Choker, f, Attribute,
|
86
|
+
84, Cigarette, m, Attribute,
|
87
|
+
85, Cigarette, f, Attribute,
|
88
|
+
86, Classic Shades, m, Attribute,
|
89
|
+
87, Classic Shades, f, Attribute,
|
90
|
+
88, Clown Eyes Blue, m, Attribute,
|
91
|
+
89, Clown Eyes Blue, f, Attribute,
|
92
|
+
90, Clown Eyes Green, m, Attribute,
|
93
|
+
91, Clown Eyes Green, f, Attribute,
|
94
|
+
92, Clown Hair Green, m, Attribute,
|
95
|
+
93, Clown Hair Green, f, Attribute,
|
96
|
+
94, Clown Nose, m, Attribute,
|
97
|
+
95, Clown Nose, f, Attribute,
|
98
|
+
96, Cowboy Hat, m, Attribute,
|
99
|
+
97, Cowboy Hat, f, Attribute,
|
100
|
+
98, Crazy Hair, m, Attribute,
|
101
|
+
99, Crazy Hair, f, Attribute,
|
102
|
+
100, Dark Hair, f, Attribute,
|
103
|
+
101, Do-rag, m, Attribute,
|
104
|
+
102, Do-rag, f, Attribute,
|
105
|
+
103, Earring, m, Attribute,
|
106
|
+
104, Earring, f, Attribute,
|
107
|
+
105, Eye Mask, m, Attribute,
|
108
|
+
106, Eye Mask, f, Attribute,
|
109
|
+
107, Eye Patch, m, Attribute,
|
110
|
+
108, Eye Patch, f, Attribute,
|
111
|
+
109, Fedora, m, Attribute,
|
112
|
+
110, Fedora, f, Attribute,
|
113
|
+
111, Front Beard, m, Attribute,
|
114
|
+
112, Front Beard Dark, m, Attribute,
|
115
|
+
113, Frown, m, Attribute,
|
116
|
+
114, Frumpy Hair, m, Attribute,
|
117
|
+
115, Frumpy Hair, f, Attribute,
|
118
|
+
116, Green Eye Shadow, f, Attribute,
|
119
|
+
117, Goat, m, Attribute,
|
120
|
+
118, Gold Chain, m, Attribute,
|
121
|
+
119, Gold Chain, f, Attribute,
|
122
|
+
120, Half Shaved, f, Attribute,
|
123
|
+
121, Handlebars, m, Attribute,
|
124
|
+
122, Headband, m, Attribute,
|
125
|
+
123, Headband, f, Attribute,
|
126
|
+
124, Hoodie, m, Attribute,
|
127
|
+
125, Hoodie, f, Attribute,
|
128
|
+
126, Horned Rim Glasses, m, Attribute,
|
129
|
+
127, Horned Rim Glasses, f, Attribute,
|
130
|
+
128, Hot Lipstick, f, Attribute,
|
131
|
+
129, Knitted Cap, m, Attribute,
|
132
|
+
130, Knitted Cap, f, Attribute,
|
133
|
+
131, Luxurious Beard, m, Attribute,
|
134
|
+
132, Medical Mask, m, Attribute,
|
135
|
+
133, Medical Mask, f, Attribute,
|
136
|
+
134, Messy Hair, m, Attribute,
|
137
|
+
135, Messy Hair, f, Attribute,
|
138
|
+
136, Mohawk, m, Attribute,
|
139
|
+
137, Mohawk, f, Attribute,
|
140
|
+
138, Mohawk Dark, m, Attribute,
|
141
|
+
139, Mohawk Dark, f, Attribute,
|
142
|
+
140, Mohawk Thin, m, Attribute,
|
143
|
+
141, Mohawk Thin, f, Attribute,
|
144
|
+
142, Mole, m, Attribute,
|
145
|
+
143, Mole, f, Attribute,
|
146
|
+
144, Mustache, m, Attribute,
|
147
|
+
145, Muttonchops, m, Attribute,
|
148
|
+
146, Nerd Glasses, m, Attribute,
|
149
|
+
147, Nerd Glasses, f, Attribute,
|
150
|
+
148, Normal Beard, m, Attribute,
|
151
|
+
149, Normal Beard Black, m, Attribute,
|
152
|
+
150, Orange Side, f, Attribute,
|
153
|
+
151, Peak Spike, m, Attribute,
|
154
|
+
152, Pigtails, f, Attribute,
|
155
|
+
153, Pilot Helmet, f, Attribute,
|
156
|
+
154, Pink with Hat, f, Attribute,
|
157
|
+
155, Pipe, m, Attribute,
|
158
|
+
156, Pipe, f, Attribute,
|
159
|
+
157, Police Cap, m, Attribute,
|
160
|
+
158, Police Cap, f, Attribute,
|
161
|
+
159, Purple Eye Shadow, f, Attribute,
|
162
|
+
160, Purple Hair, m, Attribute,
|
163
|
+
161, Purple Hair, f, Attribute,
|
164
|
+
162, Purple Lipstick, f, Attribute,
|
165
|
+
163, Red Mohawk, f, Attribute,
|
166
|
+
164, Regular Shades, m, Attribute,
|
167
|
+
165, Regular Shades, f, Attribute,
|
168
|
+
166, Rosy Cheeks, m, Attribute,
|
169
|
+
167, Rosy Cheeks, f, Attribute,
|
170
|
+
168, Shadow Beard, m, Attribute,
|
171
|
+
169, Shaved Head, m, Attribute,
|
172
|
+
170, Shaved Head, f, Attribute,
|
173
|
+
171, Silver Chain, m, Attribute,
|
174
|
+
172, Silver Chain, f, Attribute,
|
175
|
+
173, Small Shades, m, Attribute,
|
176
|
+
174, Small Shades, f, Attribute,
|
177
|
+
175, Smile, m, Attribute,
|
178
|
+
176, Spots, m, Attribute,
|
179
|
+
177, Spots, f, Attribute,
|
180
|
+
178, Straight Hair, f, Attribute,
|
181
|
+
179, Straight Hair Blonde, f, Attribute,
|
182
|
+
180, Straight Hair Dark, f, Attribute,
|
183
|
+
181, Stringy Hair, m, Attribute,
|
184
|
+
182, Stringy Hair, f, Attribute,
|
185
|
+
183, Tassle Hat, f, Attribute,
|
186
|
+
184, Tiara, f, Attribute,
|
187
|
+
185, Top Hat, m, Attribute,
|
188
|
+
186, Top Hat, f, Attribute,
|
189
|
+
187, Vampire Hair, m, Attribute,
|
190
|
+
188, Vape, m, Attribute,
|
191
|
+
189, Vape, f, Attribute,
|
192
|
+
190, VR, m, Attribute,
|
193
|
+
191, VR, f, Attribute,
|
194
|
+
192, Welding Goggles, f, Attribute,
|
195
|
+
193, Wild Blonde, f, Attribute,
|
196
|
+
194, Wild Hair, m, Attribute,
|
197
|
+
195, Wild Hair, f, Attribute,
|
198
|
+
196, Wild White Hair, f, Attribute,
|
199
|
+
197, Bear Hood, m, Attribute,
|
200
|
+
198, Bear Hood, f, Attribute,
|
201
|
+
199, Birthday Hat, m, Attribute,
|
202
|
+
200, Birthday Hat, f, Attribute,
|
203
|
+
201, Bow, f, Attribute,
|
204
|
+
202, Cigar, m, Attribute,
|
205
|
+
203, Cigar, f, Attribute,
|
206
|
+
204, Crown, m, Attribute,
|
207
|
+
205, Crown, f, Attribute,
|
208
|
+
206, Flowers, f, Attribute,
|
209
|
+
207, Frog Hood, m, Attribute,
|
210
|
+
208, Frog Hood, f, Attribute,
|
211
|
+
209, Gold Diamond Necklace, m, Attribute,
|
212
|
+
210, Gold Diamond Necklace, f, Attribute,
|
213
|
+
211, Heart Shades, m, Attribute,
|
214
|
+
212, Heart Shades, f, Attribute,
|
215
|
+
213, Jester Hat, m, Attribute,
|
216
|
+
214, Jester Hat, f, Attribute,
|
217
|
+
215, Laser Eyes, m, Attribute,
|
218
|
+
216, Laser Eyes Gold, m, Attribute,
|
219
|
+
217, Pink Lipstick, f, Attribute,
|
220
|
+
218, Red Lipstick, f, Attribute,
|
221
|
+
219, Santa Hat, m, Attribute,
|
222
|
+
220, Santa Hat, f, Attribute,
|
223
|
+
221, Silver Earring, m, Attribute,
|
224
|
+
222, Silver Earring, f, Attribute,
|
225
|
+
223, Ski Googles, m, Attribute,
|
226
|
+
224, Ski Googles, f, Attribute,
|
227
|
+
225, Sombrero, m, Attribute,
|
228
|
+
226, Sombrero, f, Attribute,
|
229
|
+
227, Sun Hat, m, Attribute,
|
230
|
+
228, Sun Hat, f, Attribute,
|
231
|
+
229, Superhero Tiara, f, Attribute,
|
232
|
+
230, Tears, m, Attribute,
|
233
|
+
231, Tears, f, Attribute,
|
234
|
+
232, Viking Helmet, m, Attribute,
|
235
|
+
233, Viking Helmet, f, Attribute,
|
236
|
+
234, Winter Hat, m, Attribute,
|
237
|
+
235, Winter Hat, f, Attribute,
|
Binary file
|
@@ -0,0 +1,162 @@
|
|
1
|
+
|
2
|
+
ROBOT_COLORS = [
|
3
|
+
'000000', # color 1 - BLACK
|
4
|
+
'535353', # color 2 - BASE 2 (DARKER)
|
5
|
+
'A4A4A4', # color 3 - BASE 1
|
6
|
+
'A9F7FF', # color 4 - BASE 3 (LIGHTER) - eyes
|
7
|
+
]
|
8
|
+
|
9
|
+
VAMPIRE_COLORS = [
|
10
|
+
'000000', # color 1 - BLACK
|
11
|
+
'131313', # color 2 - BASE 4 (DARKEST)
|
12
|
+
'535353', # color 3 - BASE 3 (DARKERER) - eyes
|
13
|
+
'A4A4A4', # color 4 - BASE 2 (DARKER) - eyes
|
14
|
+
'E0E0E0', # color 5 - BASE 1
|
15
|
+
'F6000B', # color 6 - BASE 5 - teeth - red
|
16
|
+
]
|
17
|
+
|
18
|
+
MUMMY_COLORS = [
|
19
|
+
'000000', # color 1 - BLACK
|
20
|
+
'1F1A15', # color 2 - BASE 5 (DARKEST)
|
21
|
+
'2A231C', # color 3 - BASE 4 (DARKERERER)
|
22
|
+
'5F5147', # color 4 - BASE 3 (DARKERER)
|
23
|
+
'927B6A', # color 5 - BASE 2 (DARKER)
|
24
|
+
'D9B599', # color 6 - BASE 1
|
25
|
+
'F6000B', # color 7 - BASE 6 - eyes - red
|
26
|
+
]
|
27
|
+
|
28
|
+
ORC_COLORS = [
|
29
|
+
'000000', # color 1 - BLACK
|
30
|
+
'171a08', # color 2 - BASE 3 (DARKEST)
|
31
|
+
'333F0C', # color 3 - BASE 2 (DARKER)
|
32
|
+
'50650E', # color 4 - BASE 1
|
33
|
+
'FFFFFF', # color 5 - BASE 4 - white
|
34
|
+
]
|
35
|
+
|
36
|
+
SKELETON_COLORS = [
|
37
|
+
'000000', # color 1 - BLACK
|
38
|
+
'e0e0e0', # color 2 - BASE 1
|
39
|
+
]
|
40
|
+
|
41
|
+
DEMON_COLORS = [
|
42
|
+
'000000', # color 1 - BLACK
|
43
|
+
'390102', # color 2 - BASE 3 (DARKEST) - eyes
|
44
|
+
'630006', # color 3 - BASE 2 (DARKER) - eyes
|
45
|
+
'850008', # color 4 - BASE 1
|
46
|
+
]
|
47
|
+
|
48
|
+
ZOMBIE_COLORS = [
|
49
|
+
'000000', # color 1 - BLACK
|
50
|
+
'5e7253', # color 2 - BASE 2 (DARKER)
|
51
|
+
'7da269', # color 3 - BASE 1
|
52
|
+
'ff0000', # color 4 - BASE 3 - red eye
|
53
|
+
'9bbc88', # color 5 - BASE 4 (LIGHTER)
|
54
|
+
'4a010d', # color 6 - BASE 5 - mouth (female only)
|
55
|
+
]
|
56
|
+
|
57
|
+
APE_COLORS = [
|
58
|
+
'000000', # color 1 - BLACK
|
59
|
+
'352410', # color 2 - BASE 3 (DARKEST)
|
60
|
+
'6a563f', # color 3 - BASE 2 (DARKER) - eyes
|
61
|
+
'856f56', # color 4 - BASE 1
|
62
|
+
'a98c6b', # color 5 - BASE 4 (LIGHTER) - eyes
|
63
|
+
]
|
64
|
+
|
65
|
+
ALIEN_COLORS = [
|
66
|
+
'000000', # color 1 - BLACK
|
67
|
+
'75bdbd', # color 2 - BASE 3 (DARKEST)
|
68
|
+
'9be0e0', # color 3 - BASE 2 (DARKER)
|
69
|
+
'c8fbfb', # color 4 - BASE 1
|
70
|
+
]
|
71
|
+
|
72
|
+
|
73
|
+
HUMAN_LIGHTER_BASE1 = 'ead9d9' # rgb(234 217 217) - hsl( 0° 29% 88%)
|
74
|
+
HUMAN_LIGHTER_BASE2 = 'c9b2b2' # rgb(201 178 178) - hsl( 0° 18% 74%) - eyes
|
75
|
+
HUMAN_LIGHTER_BASE3 = 'a58d8d' # rgb(165 141 141) - hsl( 0° 12% 60%) - eyes
|
76
|
+
HUMAN_LIGHTER_BASE4 = 'ffffff' # rgb(255 255 255) - hsl( 0° 0% 100%) -- white
|
77
|
+
HUMAN_LIGHTER_BASE5 = '711010' # rgb(113 16 16) - hsl( 0° 75% 25%) - mouth
|
78
|
+
|
79
|
+
HUMAN_LIGHT_BASE1 = 'dbb180' # rgb(219 177 128) - hsl( 32° 56% 68%)
|
80
|
+
HUMAN_LIGHT_BASE2 = 'd29d60' # rgb(210 157 96) - hsl( 32° 56% 60%) - eyes
|
81
|
+
HUMAN_LIGHT_BASE3 = 'a66e2c' # rgb(166 110 44) - hsl( 32° 58% 41%) - eyes
|
82
|
+
HUMAN_LIGHT_BASE4 = 'e7cba9' # rgb(231 203 169) - hsl( 33° 56% 78%)
|
83
|
+
HUMAN_LIGHT_BASE5 = '711010' # rgb(113 16 16) - hsl( 0° 75% 25%) - mouth
|
84
|
+
|
85
|
+
HUMAN_DARK_BASE1 = 'ae8b61' # rgb(174 139 97) - hsl( 33° 32% 53%)
|
86
|
+
HUMAN_DARK_BASE2 = 'a77c47' # rgb(167 124 71) - hsl( 33° 40% 47%) - eyes
|
87
|
+
HUMAN_DARK_BASE3 = '86581e' # rgb(134 88 30) - hsl( 33° 63% 32%) - eyes
|
88
|
+
HUMAN_DARK_BASE4 = 'b69f82' # rgb(182 159 130) - hsl( 33° 26% 61%)
|
89
|
+
HUMAN_DARK_BASE5 = '5f1d09' # rgb( 95 29 9) - hsl( 14° 83% 20%) - mouth
|
90
|
+
|
91
|
+
HUMAN_DARKER_BASE1 = '713f1d' # rgb(113 63 29) - hsl( 24° 59% 28%)
|
92
|
+
HUMAN_DARKER_BASE2 = '723709' # rgb(114 55 9) - hsl( 26° 85% 24%) - eyes
|
93
|
+
HUMAN_DARKER_BASE3 = '562600' # rgb( 86 38 0) - hsl( 27° 100% 17%) - eyes
|
94
|
+
HUMAN_DARKER_BASE4 = '8b532c' # rgb(139 83 44) - hsl( 25° 52% 36%)
|
95
|
+
HUMAN_DARKER_BASE5 = '4a1201' # rgb( 74 18 1) - hsl( 14° 97% 15%) - mouth
|
96
|
+
|
97
|
+
|
98
|
+
HUMAN_COLORS_LIGHT = [ ## todo/check: change to HUMAN_LIGHT_COLORS???
|
99
|
+
'000000', # color 1 - BLACK
|
100
|
+
HUMAN_LIGHT_BASE3, # color 2 - BASE 3 (DARKEST) - eyes
|
101
|
+
HUMAN_LIGHT_BASE2, # color 3 - BASE 2 (DARKER) - eyes
|
102
|
+
HUMAN_LIGHT_BASE1, # color 4 - BASE 1
|
103
|
+
HUMAN_LIGHT_BASE4, # color 5 - BASE 4
|
104
|
+
HUMAN_LIGHT_BASE5, # color 6 - BASE 5 - mouth (femaly only)
|
105
|
+
]
|
106
|
+
|
107
|
+
HUMAN_COLORS_LIGHTER = [ ## todo/check: change to HUMAN_LIGHTER_COLORS?? or add alias - why? why not?
|
108
|
+
'000000', # color 1 - BLACK
|
109
|
+
HUMAN_LIGHTER_BASE3,
|
110
|
+
HUMAN_LIGHTER_BASE2,
|
111
|
+
HUMAN_LIGHTER_BASE1,
|
112
|
+
HUMAN_LIGHTER_BASE4,
|
113
|
+
HUMAN_LIGHTER_BASE5,
|
114
|
+
]
|
115
|
+
|
116
|
+
HUMAN_COLORS_DARK = [
|
117
|
+
'000000', # color 1 - BLACK
|
118
|
+
HUMAN_DARK_BASE3,
|
119
|
+
HUMAN_DARK_BASE2,
|
120
|
+
HUMAN_DARK_BASE1,
|
121
|
+
HUMAN_DARK_BASE4,
|
122
|
+
HUMAN_DARK_BASE5,
|
123
|
+
]
|
124
|
+
|
125
|
+
HUMAN_COLORS_DARKER = [
|
126
|
+
'000000', # color 1 - BLACK
|
127
|
+
HUMAN_DARKER_BASE3,
|
128
|
+
HUMAN_DARKER_BASE2,
|
129
|
+
HUMAN_DARKER_BASE1,
|
130
|
+
HUMAN_DARKER_BASE4,
|
131
|
+
HUMAN_DARKER_BASE5,
|
132
|
+
]
|
133
|
+
|
134
|
+
|
135
|
+
HUMAN_COLORS = {
|
136
|
+
'light' => HUMAN_COLORS_LIGHT,
|
137
|
+
'lighter' => HUMAN_COLORS_LIGHTER,
|
138
|
+
'dark' => HUMAN_COLORS_DARK,
|
139
|
+
'darker' => HUMAN_COLORS_DARKER,
|
140
|
+
}
|
141
|
+
|
142
|
+
|
143
|
+
|
144
|
+
### todo/check:
|
145
|
+
## use a different name other than the "generic" COLORS - why? why not?
|
146
|
+
|
147
|
+
COLORS = {
|
148
|
+
## original series
|
149
|
+
'human' => HUMAN_COLORS,
|
150
|
+
'zombie' => ZOMBIE_COLORS,
|
151
|
+
'ape' => APE_COLORS,
|
152
|
+
'alien' => ALIEN_COLORS,
|
153
|
+
## more series
|
154
|
+
'vampire' => VAMPIRE_COLORS,
|
155
|
+
'mummy' => MUMMY_COLORS,
|
156
|
+
'orc' => ORC_COLORS,
|
157
|
+
'skeleton' => SKELETON_COLORS,
|
158
|
+
'demon' => DEMON_COLORS,
|
159
|
+
'robot' => ROBOT_COLORS,
|
160
|
+
}
|
161
|
+
|
162
|
+
|
@@ -1,68 +1,38 @@
|
|
1
1
|
module Cryptopunks
|
2
|
-
|
3
|
-
class
|
2
|
+
## note: was Image::Composite
|
3
|
+
class ImageComposite < Pixelart::ImageComposite
|
4
4
|
|
5
|
+
PUNK_HASH = 'ac39af4793119ee46bbff351d8cb6b5f23da60222126add4268e261199a2921b'
|
5
6
|
|
6
|
-
def self.
|
7
|
-
|
8
|
-
|
7
|
+
def self.sha256( data )
|
8
|
+
## todo/check: or just use Digest::SHA256.hexdigest - why? why not?
|
9
|
+
Digest::SHA256.digest( data ).unpack( 'H*' )[0]
|
9
10
|
end
|
10
11
|
|
11
|
-
PUNK_ROWS = 100
|
12
|
-
PUNK_COLS = 100
|
13
|
-
PUNK_COUNT = PUNK_ROWS * PUNK_COLS ## 10_000 = 100x100 (24000x24000 pixel)
|
14
12
|
|
15
13
|
PUNK_HEIGHT = 24
|
16
14
|
PUNK_WIDTH = 24
|
17
15
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
def initialize( data )
|
23
|
-
@punks = ChunkyPNG::Image.from_blob( data )
|
24
|
-
puts " #{@punks.height}x#{@punks.width} (height x width)"
|
16
|
+
def self.read( path='./punks.png', width: PUNK_WIDTH, height: PUNK_HEIGHT )
|
17
|
+
data = File.open( path, 'rb' ) { |f| f.read }
|
25
18
|
|
26
|
-
## check sha256 checksum
|
27
|
-
|
28
|
-
|
29
|
-
puts " >#{@hexdigest}< SHA256 hash matching"
|
19
|
+
hexdigest = sha256( data ) ## check sha256 checksum
|
20
|
+
if hexdigest == PUNK_HASH
|
21
|
+
puts " >#{hexdigest}< SHA256 hash matching"
|
30
22
|
puts " ✓ True Official Genuine CryptoPunks™ verified"
|
31
23
|
else
|
32
|
-
puts "
|
33
|
-
puts " >#{PUNK_HASH}< expected for True Official Genuine CryptoPunks™."
|
34
|
-
puts ""
|
35
|
-
puts " Sorry, please download the original."
|
36
|
-
exit 1
|
24
|
+
puts " ✓ True Official Genuine Yes, You Can! Punks Not Dead™ verified"
|
37
25
|
end
|
38
|
-
end
|
39
26
|
|
40
|
-
|
41
|
-
|
42
|
-
## todo/check: or just use Digest::SHA256.hexdigest - why? why not?
|
43
|
-
Digest::SHA256.digest( data ).unpack( 'H*' )[0]
|
27
|
+
img = ChunkyPNG::Image.from_blob( data )
|
28
|
+
new( img, width: width, height: height )
|
44
29
|
end
|
45
30
|
|
46
31
|
|
47
|
-
def
|
48
|
-
|
49
|
-
|
50
|
-
alias_method :genuine?, :verify?
|
51
|
-
alias_method :original?, :verify?
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
def size() PUNK_COUNT; end
|
56
|
-
|
57
|
-
|
58
|
-
def punk( index )
|
59
|
-
y, x = index.divmod( PUNK_ROWS )
|
60
|
-
img = @punks.crop( x*PUNK_WIDTH, y*PUNK_HEIGHT, PUNK_WIDTH, PUNK_HEIGHT )
|
61
|
-
Pixelart::Image.new( img.width, img.height, img ) ## wrap in pixelart image
|
32
|
+
def initialize( *args, width: PUNK_WIDTH,
|
33
|
+
height: PUNK_HEIGHT )
|
34
|
+
super
|
62
35
|
end
|
63
|
-
alias_method :[], :punk
|
64
|
-
|
65
36
|
|
66
|
-
end ## class
|
67
|
-
end ## class Image
|
37
|
+
end ## class ImageComposite
|
68
38
|
end ## module Cryptopunks
|
@@ -0,0 +1,204 @@
|
|
1
|
+
|
2
|
+
module Cryptopunks
|
3
|
+
|
4
|
+
class Metadata
|
5
|
+
### todo/fix:
|
6
|
+
## move into Punks::Metadata or such
|
7
|
+
class Sprite
|
8
|
+
attr_reader :id, :name, :type, :gender
|
9
|
+
|
10
|
+
|
11
|
+
def initialize( id:,
|
12
|
+
name:,
|
13
|
+
type:,
|
14
|
+
gender: )
|
15
|
+
@id = id # zero-based index eg. 0,1,2,3, etc.
|
16
|
+
@name = name
|
17
|
+
@type = type
|
18
|
+
@gender = gender
|
19
|
+
end
|
20
|
+
|
21
|
+
## todo/check - find better names for type attribute/archetypes?
|
22
|
+
## use (alternate name/alias) base or face for archetypes? any others?
|
23
|
+
def attribute?() @type.downcase.start_with?( 'attribute' ); end
|
24
|
+
def archetype?() @type.downcase.start_with?( 'archetype' ); end
|
25
|
+
end # class Metadata::Sprite
|
26
|
+
end # class Metadata
|
27
|
+
|
28
|
+
|
29
|
+
|
30
|
+
|
31
|
+
class Generator
|
32
|
+
|
33
|
+
######
|
34
|
+
# static helpers - (turn into "true" static self.class methods - why? why not?)
|
35
|
+
#
|
36
|
+
def normalize_key( str )
|
37
|
+
str.downcase.gsub(/[ ()°_-]/, '').strip
|
38
|
+
end
|
39
|
+
|
40
|
+
def normalize_gender( str )
|
41
|
+
## e.g. Female => f
|
42
|
+
## F => f
|
43
|
+
## always return f or m
|
44
|
+
str.downcase[0]
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
def build_attributes_by_name( recs )
|
49
|
+
h = {}
|
50
|
+
recs.each_with_index do |rec|
|
51
|
+
key = normalize_key( rec.name )
|
52
|
+
key << "_(#{rec.gender})" if rec.attribute?
|
53
|
+
|
54
|
+
if h[ key ]
|
55
|
+
puts "!!! ERROR - attribute name is not unique:"
|
56
|
+
pp rec
|
57
|
+
puts "duplicate:"
|
58
|
+
pp h[key]
|
59
|
+
exit 1
|
60
|
+
end
|
61
|
+
h[ key ] = rec
|
62
|
+
end
|
63
|
+
## pp h
|
64
|
+
h
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
def build_recs( recs ) ## build and normalize (meta data) records
|
69
|
+
|
70
|
+
## sort by id
|
71
|
+
recs = recs.sort do |l,r|
|
72
|
+
l['id'].to_i( 10 ) <=> r['id'].to_i( 10 ) # use base10 (decimal)
|
73
|
+
end
|
74
|
+
|
75
|
+
## assert all recs are in order by id (0 to size)
|
76
|
+
recs.each_with_index do |rec, exp_id|
|
77
|
+
id = rec['id'].to_i(10)
|
78
|
+
if id != exp_id
|
79
|
+
puts "!! ERROR - meta data record ids out-of-order - expected id #{exp_id}; got #{id}"
|
80
|
+
exit 1
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
## convert to "wrapped / immutable" kind-of struct
|
85
|
+
recs = recs.map do |rec|
|
86
|
+
id = rec['id'].to_i( 10 )
|
87
|
+
name = rec['name']
|
88
|
+
gender = normalize_gender( rec['gender'] )
|
89
|
+
type = rec['type']
|
90
|
+
|
91
|
+
Metadata::Sprite.new(
|
92
|
+
id: id,
|
93
|
+
name: name,
|
94
|
+
type: type,
|
95
|
+
gender: gender)
|
96
|
+
end
|
97
|
+
recs
|
98
|
+
end # method build_recs
|
99
|
+
|
100
|
+
|
101
|
+
|
102
|
+
|
103
|
+
def initialize( image_path="./spritesheet.png",
|
104
|
+
meta_path="./spritesheet.csv" )
|
105
|
+
@sheet = Pixelart::ImageComposite.read( image_path )
|
106
|
+
recs = CsvHash.read( meta_path )
|
107
|
+
|
108
|
+
@recs = build_recs( recs )
|
109
|
+
|
110
|
+
## lookup by "case/space-insensitive" name / key
|
111
|
+
@attributes_by_name = build_attributes_by_name( @recs )
|
112
|
+
end
|
113
|
+
|
114
|
+
|
115
|
+
def spritesheet() @sheet; end
|
116
|
+
alias_method :sheet, :spritesheet
|
117
|
+
|
118
|
+
|
119
|
+
|
120
|
+
|
121
|
+
|
122
|
+
def find_meta( q, gender: nil ) ## gender (m/f) required for attributes!!!
|
123
|
+
|
124
|
+
key = normalize_key( q ) ## normalize q(uery) string/symbol
|
125
|
+
key << "_(#{normalize_gender( gender )})" if gender
|
126
|
+
|
127
|
+
rec = @attributes_by_name[ key ]
|
128
|
+
if rec
|
129
|
+
puts " lookup >#{key}< => #{rec.id}: #{rec.name} / #{rec.type} (#{rec.gender})"
|
130
|
+
# pp rec
|
131
|
+
else
|
132
|
+
puts "!! WARN - no lookup found for key >#{key}<"
|
133
|
+
end
|
134
|
+
rec
|
135
|
+
end
|
136
|
+
|
137
|
+
|
138
|
+
def find( q, gender: nil ) ## gender (m/f) required for attributes!!!
|
139
|
+
rec = find_meta( q, gender: gender )
|
140
|
+
|
141
|
+
## return image if record found
|
142
|
+
rec ? @sheet[ rec.id ] : nil
|
143
|
+
end
|
144
|
+
|
145
|
+
|
146
|
+
|
147
|
+
|
148
|
+
def to_recs( *values )
|
149
|
+
archetype_name = values[0]
|
150
|
+
|
151
|
+
### todo/fix: check for nil/not found!!!!
|
152
|
+
archetype = find_meta( archetype_name )
|
153
|
+
if archetype.nil?
|
154
|
+
puts "!! ERROR - archetype >#{archetype}< not found; sorry"
|
155
|
+
exit 1
|
156
|
+
end
|
157
|
+
|
158
|
+
recs = [archetype]
|
159
|
+
|
160
|
+
attribute_names = values[1..-1]
|
161
|
+
## note: attribute lookup requires gender from archetype!!!!
|
162
|
+
attribute_gender = archetype.gender
|
163
|
+
|
164
|
+
attribute_names.each do |attribute_name|
|
165
|
+
attribute = find_meta( attribute_name, gender: attribute_gender )
|
166
|
+
if attribute.nil?
|
167
|
+
puts "!! ERROR - attribute >#{attribute_name}< for (#{attribute_gender}) not found; sorry"
|
168
|
+
exit 1
|
169
|
+
end
|
170
|
+
recs << attribute
|
171
|
+
end
|
172
|
+
|
173
|
+
recs
|
174
|
+
end
|
175
|
+
|
176
|
+
|
177
|
+
|
178
|
+
|
179
|
+
def generate_image( *values, background: nil )
|
180
|
+
|
181
|
+
ids = if values[0].is_a?( Integer ) ## assume integer number (indexes)
|
182
|
+
values
|
183
|
+
else ## assume strings (names)
|
184
|
+
to_recs( *values ).map { |rec| rec.id }
|
185
|
+
end
|
186
|
+
|
187
|
+
|
188
|
+
punk = Pixelart::Image.new( 24, 24 )
|
189
|
+
|
190
|
+
if background ## for now assume background is (simply) color
|
191
|
+
punk.compose!( Pixelart::Image.new( 24, 24, background ) )
|
192
|
+
end
|
193
|
+
|
194
|
+
ids.each do |id|
|
195
|
+
punk.compose!( @sheet[ id ] )
|
196
|
+
end
|
197
|
+
|
198
|
+
punk
|
199
|
+
end
|
200
|
+
alias_method :generate, :generate_image
|
201
|
+
|
202
|
+
end # class Generator
|
203
|
+
|
204
|
+
end # module Cryptopunks
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Cryptopunks
|
2
|
+
|
3
|
+
|
4
|
+
|
5
|
+
class Image
|
6
|
+
|
7
|
+
def self.read( path ) ## convenience helper
|
8
|
+
img = ChunkyPNG::Image.from_file( path )
|
9
|
+
new( img )
|
10
|
+
end
|
11
|
+
|
12
|
+
|
13
|
+
|
14
|
+
### keep design & colors keyword args in c'tor here
|
15
|
+
## or use parse() like in pixelart - why? why not?
|
16
|
+
|
17
|
+
def initialize( initial=nil, design: nil,
|
18
|
+
colors: nil )
|
19
|
+
if initial
|
20
|
+
## pass image through as-is
|
21
|
+
img = initial
|
22
|
+
else
|
23
|
+
## note: unwrap inner image before passing on to super c'tor
|
24
|
+
img = Pixelart::Image.parse( design, colors: colors ).image
|
25
|
+
end
|
26
|
+
|
27
|
+
super( img.width, img.height, img )
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
|
32
|
+
end # class Image
|
33
|
+
end # module Cryptopunks
|
data/lib/cryptopunks/structs.rb
CHANGED
@@ -137,12 +137,25 @@ end ## (nested) class Accessory
|
|
137
137
|
@birthday = Date.new( 2017, 6, 23) ## all 10,000 minted on June 23, 2017
|
138
138
|
end
|
139
139
|
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
def
|
145
|
-
def
|
140
|
+
def is_type?( name ) @type.name == name; end
|
141
|
+
alias_method :is?, :is_type?
|
142
|
+
|
143
|
+
## convenience helpers for "classic" (5) types
|
144
|
+
def alien?() is_type?( 'Alien'); end
|
145
|
+
def ape?() is_type?( 'Ape' ); end
|
146
|
+
def zombie?() is_type?( 'Zombie' ); end
|
147
|
+
def female?() is_type?( 'Female' ); end
|
148
|
+
def male?() is_type?( 'Male' ); end
|
149
|
+
|
150
|
+
## convenience helpers to lookup attributes
|
151
|
+
def has_attribute?( name )
|
152
|
+
accessories.each do |acc|
|
153
|
+
return true if acc.name == name
|
154
|
+
end
|
155
|
+
false
|
156
|
+
end
|
157
|
+
alias_method :has?, :has_attribute?
|
158
|
+
alias_method :include?, :has_attribute?
|
146
159
|
end # class Metadata
|
147
160
|
|
148
161
|
end # module Cryptopunks
|
data/lib/cryptopunks/version.rb
CHANGED
data/lib/cryptopunks.rb
CHANGED
@@ -1,22 +1,77 @@
|
|
1
1
|
## 3rd party
|
2
|
-
require 'pixelart'
|
2
|
+
require 'pixelart/base'
|
3
3
|
require 'csvreader'
|
4
4
|
|
5
5
|
|
6
6
|
|
7
7
|
## extra stdlibs
|
8
|
-
require 'digest'
|
8
|
+
require 'digest' ## move/add to pixelart upstream - why? why not?
|
9
9
|
require 'optparse'
|
10
10
|
|
11
11
|
|
12
12
|
|
13
13
|
## our own code
|
14
14
|
require 'cryptopunks/version' # note: let version always go first
|
15
|
+
|
16
|
+
## forward define superclass for image
|
17
|
+
module Cryptopunks
|
18
|
+
class Image < Pixelart::Image; end
|
19
|
+
end
|
20
|
+
|
21
|
+
|
15
22
|
require 'cryptopunks/attributes'
|
16
23
|
require 'cryptopunks/structs'
|
17
24
|
require 'cryptopunks/composite'
|
25
|
+
## add old backwards compatible alias
|
26
|
+
|
27
|
+
module Cryptopunks
|
28
|
+
class Image
|
29
|
+
Composite = ImageComposite
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
|
18
34
|
require 'cryptopunks/dataset'
|
19
35
|
|
36
|
+
require 'cryptopunks/colors'
|
37
|
+
require 'cryptopunks/image'
|
38
|
+
|
39
|
+
require 'cryptopunks/generator'
|
40
|
+
|
41
|
+
###
|
42
|
+
## add convenience pre-configurated generatored with build-in spritesheet (see config)
|
43
|
+
|
44
|
+
module Cryptopunks
|
45
|
+
|
46
|
+
def self.generator
|
47
|
+
@generator ||= Generator.new( "#{root}/config/spritesheet.png",
|
48
|
+
"#{root}/config/spritesheet.csv" )
|
49
|
+
end
|
50
|
+
|
51
|
+
class Image
|
52
|
+
def self.generate( *values )
|
53
|
+
img = Cryptopunks.generator.generate( *values )
|
54
|
+
## note: unwrap inner image before passing on to c'tor (requires ChunkyPNG image for now)
|
55
|
+
new( img.image )
|
56
|
+
end
|
57
|
+
end # class Image
|
58
|
+
|
59
|
+
|
60
|
+
class Spritesheet
|
61
|
+
## note: for now class used for "namespace" only
|
62
|
+
def self.find_by( name:, gender: nil ) ## return archetype/attribute image by name
|
63
|
+
# note: pass along name as q (query string)
|
64
|
+
Cryptopunks.generator.find( name, gender: gender )
|
65
|
+
end
|
66
|
+
end # class Spritesheet
|
67
|
+
## add convenience (alternate spelling) alias - why? why not?
|
68
|
+
SpriteSheet = Spritesheet
|
69
|
+
Sheet = Spritesheet
|
70
|
+
end # module Cryptopunks
|
71
|
+
|
72
|
+
|
73
|
+
|
74
|
+
|
20
75
|
|
21
76
|
|
22
77
|
module Cryptopunks
|
@@ -25,6 +80,7 @@ class Tool
|
|
25
80
|
opts = { zoom: 1,
|
26
81
|
outdir: '.',
|
27
82
|
file: './punks.png',
|
83
|
+
offset: 0,
|
28
84
|
}
|
29
85
|
|
30
86
|
parser = OptionParser.new do |cmd|
|
@@ -46,6 +102,9 @@ class Tool
|
|
46
102
|
opts[:file] = file
|
47
103
|
end
|
48
104
|
|
105
|
+
cmd.on("--offset=NUM", "Start counting at offset (default: #{opts[:offset]})", Integer ) do |offset|
|
106
|
+
opts[:offset] = offset
|
107
|
+
end
|
49
108
|
|
50
109
|
cmd.on("-h", "--help", "Prints this help") do
|
51
110
|
puts cmd
|
@@ -59,7 +118,7 @@ class Tool
|
|
59
118
|
pp opts
|
60
119
|
|
61
120
|
puts "==> reading >#{opts[:file]}<..."
|
62
|
-
punks =
|
121
|
+
punks = ImageComposite.read( opts[:file] )
|
63
122
|
|
64
123
|
|
65
124
|
puts " setting zoom to #{opts[:zoom]}x" if opts[:zoom] != 1
|
@@ -72,7 +131,7 @@ class Tool
|
|
72
131
|
|
73
132
|
punk = punks[ punk_index ]
|
74
133
|
|
75
|
-
punk_name
|
134
|
+
punk_name = "punk-" + "%04d" % (punk_index + opts[:offset])
|
76
135
|
|
77
136
|
## if zoom - add x2,x4 or such
|
78
137
|
if opts[:zoom] != 1
|
@@ -81,7 +140,7 @@ class Tool
|
|
81
140
|
end
|
82
141
|
|
83
142
|
path = "#{opts[:outdir]}/#{punk_name}.png"
|
84
|
-
puts "==> (#{index+1}/#{args.size}) minting punk ##{punk_index}; writing to >#{path}<..."
|
143
|
+
puts "==> (#{index+1}/#{args.size}) minting punk ##{punk_index+opts[:offset]}; writing to >#{path}<..."
|
85
144
|
|
86
145
|
punk.save( path )
|
87
146
|
end
|
@@ -98,6 +157,7 @@ end ## module Cryptopunks
|
|
98
157
|
|
99
158
|
|
100
159
|
|
160
|
+
|
101
161
|
### add some convenience shortcuts
|
102
162
|
CryptoPunks = Cryptopunks
|
103
163
|
Punks = Cryptopunks
|
@@ -105,4 +165,10 @@ Punks = Cryptopunks
|
|
105
165
|
|
106
166
|
|
107
167
|
|
168
|
+
###
|
169
|
+
# note: for convenience auto include Pixelart namespace!!! - why? why not?
|
170
|
+
include Pixelart
|
171
|
+
|
172
|
+
|
173
|
+
|
108
174
|
puts Cryptopunks.banner # say hello
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cryptopunks
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gerald Bauer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-10-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pixelart
|
@@ -91,10 +91,15 @@ files:
|
|
91
91
|
- Rakefile
|
92
92
|
- bin/cryptopunk
|
93
93
|
- bin/punk
|
94
|
+
- config/spritesheet.csv
|
95
|
+
- config/spritesheet.png
|
94
96
|
- lib/cryptopunks.rb
|
95
97
|
- lib/cryptopunks/attributes.rb
|
98
|
+
- lib/cryptopunks/colors.rb
|
96
99
|
- lib/cryptopunks/composite.rb
|
97
100
|
- lib/cryptopunks/dataset.rb
|
101
|
+
- lib/cryptopunks/generator.rb
|
102
|
+
- lib/cryptopunks/image.rb
|
98
103
|
- lib/cryptopunks/structs.rb
|
99
104
|
- lib/cryptopunks/version.rb
|
100
105
|
homepage: https://github.com/cryptopunksnotdead/cryptopunks
|