cryptopunks 1.0.0 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,33 @@
1
+ ###
2
+ # human (female) - basic - zero attributes
3
+ #
4
+ # colors:
5
+ # 0 - transparent
6
+ # 1 - black
7
+ #
8
+ # size: 24x24
9
+
10
+ . . . . . . . . . . . . . . . . . . . . . . . .
11
+ . . . . . . . . . . . . . . . . . . . . . . . .
12
+ . . . . . . . . . . . . . . . . . . . . . . . .
13
+ . . . . . . . . . . . . . . . . . . . . . . . .
14
+ . . . . . . . . . . . . . . . . . . . . . . . .
15
+ . . . . . . . . . . . . . . . . . . . . . . . .
16
+ . . . . . . . . . . . . . . . . . . . . . . . .
17
+ . . . . . . . . . @ @ @ @ @ @ . . . . . . . . .
18
+ . . . . . . . . @ ^ ^ ^ ^ ^ ^ @ . . . . . . . .
19
+ . . . . . . . @ ^ ~ ^ ^ ^ ^ ^ ^ @ . . . . . . .
20
+ . . . . . . . @ ^ ^ ^ ^ ^ ^ ^ ^ @ . . . . . . .
21
+ . . . . . . . @ ^ ^ ^ ^ ^ ^ ^ ^ @ . . . . . . .
22
+ . . . . . . @ ^ ^ x x ^ ^ ^ x x @ . . . . . . .
23
+ . . . . . . @ ^ ^ @ o ^ ^ ^ @ o @ . . . . . . .
24
+ . . . . . . @ @ ^ ^ ^ ^ ^ ^ ^ ^ @ . . . . . . .
25
+ . . . . . . . @ ^ ^ ^ ^ ^ ^ ^ ^ @ . . . . . . .
26
+ . . . . . . . @ ^ ^ ^ ^ @ ^ ^ ^ @ . . . . . . .
27
+ . . . . . . . @ ^ ^ ^ ^ ^ ^ ^ ^ @ . . . . . . .
28
+ . . . . . . . @ ^ ^ ^ % % % ^ ^ @ . . . . . . .
29
+ . . . . . . . . @ ^ ^ ^ ^ ^ ^ @ . . . . . . . .
30
+ . . . . . . . . @ ^ @ ^ ^ ^ @ . . . . . . . . .
31
+ . . . . . . . . @ ^ ^ @ @ @ . . . . . . . . . .
32
+ . . . . . . . . @ ^ ^ ^ @ . . . . . . . . . . .
33
+ . . . . . . . . @ ^ ^ ^ @ . . . . . . . . . . .
@@ -0,0 +1,34 @@
1
+ ###
2
+ # human (male) - basic - zero attributes
3
+ #
4
+ # colors:
5
+ # 0 - transparent
6
+ # 1 - black
7
+ #
8
+ # size: 24x24
9
+
10
+ . . . . . . . . . . . . . . . . . . . . . . . .
11
+ . . . . . . . . . . . . . . . . . . . . . . . .
12
+ . . . . . . . . . . . . . . . . . . . . . . . .
13
+ . . . . . . . . . . . . . . . . . . . . . . . .
14
+ . . . . . . . . . . . . . . . . . . . . . . . .
15
+ . . . . . . . . @ @ @ @ @ @ @ . . . . . . . . .
16
+ . . . . . . . @ ^ ^ ^ ^ ^ ^ ^ @ . . . . . . . .
17
+ . . . . . . @ ^ ^ ~ ^ ^ ^ ^ ^ ^ @ . . . . . . .
18
+ . . . . . . @ ^ ~ ^ ^ ^ ^ ^ ^ ^ @ . . . . . . .
19
+ . . . . . . @ ^ ^ ^ ^ ^ ^ ^ ^ ^ @ . . . . . . .
20
+ . . . . . . @ ^ ^ ^ ^ ^ ^ ^ ^ ^ @ . . . . . . .
21
+ . . . . . . @ ^ ^ x x ^ ^ ^ x x @ . . . . . . .
22
+ . . . . . @ ^ ^ ^ @ o ^ ^ ^ @ o @ . . . . . . .
23
+ . . . . . @ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ @ . . . . . . .
24
+ . . . . . @ @ ^ ^ ^ ^ ^ ^ ^ ^ ^ @ . . . . . . .
25
+ . . . . . . @ ^ ^ ^ ^ ^ @ @ ^ ^ @ . . . . . . .
26
+ . . . . . . @ ^ ^ ^ ^ ^ ^ ^ ^ ^ @ . . . . . . .
27
+ . . . . . . @ ^ ^ ^ ^ ^ ^ ^ ^ ^ @ . . . . . . .
28
+ . . . . . . @ ^ ^ ^ ^ @ @ @ ^ ^ @ . . . . . . .
29
+ . . . . . . @ ^ ^ ^ ^ ^ ^ ^ ^ ^ @ . . . . . . .
30
+ . . . . . . @ ^ ^ ^ ^ ^ ^ ^ ^ @ . . . . . . . .
31
+ . . . . . . @ ^ ^ ^ @ @ @ @ @ . . . . . . . . .
32
+ . . . . . . @ ^ ^ ^ @ . . . . . . . . . . . . .
33
+ . . . . . . @ ^ ^ ^ @ . . . . . . . . . . . . .
34
+
@@ -0,0 +1,33 @@
1
+ ###
2
+ # zombie (male) - basic - zero attributes
3
+ #
4
+ # colors:
5
+ # 0 - transparent
6
+ # 1 - black
7
+ #
8
+ # size: 24x24
9
+
10
+ . . . . . . . . . . . . . . . . . . . . . . . .
11
+ . . . . . . . . . . . . . . . . . . . . . . . .
12
+ . . . . . . . . . . . . . . . . . . . . . . . .
13
+ . . . . . . . . . . . . . . . . . . . . . . . .
14
+ . . . . . . . . . . . . . . . . . . . . . . . .
15
+ . . . . . . . . @ @ @ @ @ @ @ . . . . . . . . .
16
+ . . . . . . . @ o o o o o o o @ . . . . . . . .
17
+ . . . . . . @ o o ~ o o o o o o @ . . . . . . .
18
+ . . . . . . @ o ~ o o o o o o o @ . . . . . . .
19
+ . . . . . . @ o o o o o o o o o @ . . . . . . .
20
+ . . . . . . @ o o o o o o o o o @ . . . . . . .
21
+ . . . . . . @ o o x x o o o x x @ . . . . . . .
22
+ . . . . . @ o o o ^ @ o o o ^ @ @ . . . . . . .
23
+ . . . . . @ o o o x o o o o x o @ . . . . . . .
24
+ . . . . . @ @ o o o o o o o o o @ . . . . . . .
25
+ . . . . . . @ o o o o o @ @ o o @ . . . . . . .
26
+ . . . . . . @ o o o o o o o o o @ . . . . . . .
27
+ . . . . . . @ o o o o o o o o o @ . . . . . . .
28
+ . . . . . . @ o o o o @ @ @ o o @ . . . . . . .
29
+ . . . . . . @ o o o o x o o o o @ . . . . . . .
30
+ . . . . . . @ o o o o o o o o @ . . . . . . . .
31
+ . . . . . . @ o o o @ @ @ @ @ . . . . . . . . .
32
+ . . . . . . @ o o o @ . . . . . . . . . . . . .
33
+ . . . . . . @ o o o @ . . . . . . . . . . . . .
data/lib/cryptopunks.rb CHANGED
@@ -1,9 +1,11 @@
1
1
  ## 3rd party
2
- require 'crypto-lite'
3
- require 'chunky_png'
2
+ require 'pixelart/base'
3
+ require 'csvreader'
4
+
5
+
4
6
 
5
7
  ## extra stdlibs
6
- require 'fileutils'
8
+ require 'digest'
7
9
  require 'optparse'
8
10
 
9
11
 
@@ -11,102 +13,33 @@ require 'optparse'
11
13
  ## our own code
12
14
  require 'cryptopunks/version' # note: let version always go first
13
15
 
14
-
16
+ ## forward define superclass for image
15
17
  module Cryptopunks
16
- class Image
17
- def self.read( path='./punks.png' )
18
- data = File.open( path, 'rb' ) { |f| f.read }
19
- new( data )
20
- end
21
-
22
-
23
- attr_accessor :zoom
24
-
25
- PUNK_ROWS = 100
26
- PUNK_COLS = 100
27
- PUNK_COUNT = PUNK_ROWS * PUNK_COLS ## 10_000 = 100x100 (24000x24000 pixel)
28
-
29
- PUNK_HEIGHT = 24
30
- PUNK_WIDTH = 24
31
-
32
- PUNK_HASH = 'ac39af4793119ee46bbff351d8cb6b5f23da60222126add4268e261199a2921b'
33
-
34
-
35
- def initialize( data )
36
- @punks = ChunkyPNG::Image.from_blob( data )
37
- puts " #{@punks.height}x#{@punks.width} (height x width)"
38
-
39
- ## check sha256 checksum
40
- @hexdigest = sha256( data )
41
- if original?
42
- puts " >#{@hexdigest}< SHA256 hash matching"
43
- puts " ✓ True Official Genuine CryptoPunks™ verified"
44
- else
45
- puts " !! ERROR: >#{hexdigest}< SHA256 hash NOT matching"
46
- puts " >#{PUNK_HASH}< expected for True Official Genuine CryptoPunks™."
47
- puts ""
48
- puts " Sorry, please download the original."
49
- exit 1
50
- end
51
-
52
- @zoom = 1
53
- end
54
-
55
-
56
- def hexdigest() @hexdigest end
57
-
58
- def verify?() @hexdigest == PUNK_HASH; end
59
- alias_method :genuine?, :verify?
60
- alias_method :original?, :verify?
61
-
62
-
63
-
64
- def size() PUNK_COUNT; end
65
-
66
- def []( index )
67
- @zoom == 1 ? crop( index ) : scale( index, @zoom )
68
- end
69
-
70
-
71
- def crop( index )
72
- y, x = index.divmod( PUNK_ROWS )
73
- @punks.crop( x*PUNK_WIDTH, y*PUNK_HEIGHT, PUNK_WIDTH, PUNK_HEIGHT )
74
- end
75
-
18
+ class Image < Pixelart::Image; end
19
+ end
76
20
 
77
- def scale( index, zoom )
78
- punk = ChunkyPNG::Image.new( PUNK_WIDTH*zoom, PUNK_HEIGHT*zoom,
79
- ChunkyPNG::Color::WHITE )
80
21
 
81
- ## (x,y) offset in big all-in-one punks image
82
- y, x = index.divmod( PUNK_ROWS )
22
+ require 'cryptopunks/attributes'
23
+ require 'cryptopunks/structs'
24
+ require 'cryptopunks/composite'
25
+ require 'cryptopunks/dataset'
83
26
 
84
- ## copy all 24x24 pixels
85
- PUNK_WIDTH.times do |i|
86
- PUNK_HEIGHT.times do |j|
87
- pixel = @punks[i+x*PUNK_WIDTH, j+y*PUNK_HEIGHT]
88
- zoom.times do |n|
89
- zoom.times do |m|
90
- punk[n+zoom*i,m+zoom*j] = pixel
91
- end
92
- end
93
- end
94
- end
95
- punk
96
- end
97
- end ## class Image
27
+ require 'cryptopunks/colors'
28
+ require 'cryptopunks/image'
98
29
 
99
30
 
100
31
 
32
+ module Cryptopunks
101
33
  class Tool
102
34
  def run( args )
103
35
  opts = { zoom: 1,
104
36
  outdir: '.',
105
37
  file: './punks.png',
38
+ offset: 0,
106
39
  }
107
40
 
108
41
  parser = OptionParser.new do |cmd|
109
- cmd.banner = "Usage: cryptopunks [options] IDs"
42
+ cmd.banner = "Usage: punk (or cryptopunk) [options] IDs"
110
43
 
111
44
  cmd.separator " Mint punk characters from composite (#{opts[:file]}) - for IDs use 0 to 9999"
112
45
  cmd.separator ""
@@ -124,6 +57,9 @@ class Tool
124
57
  opts[:file] = file
125
58
  end
126
59
 
60
+ cmd.on("--offset=NUM", "Start counting at offset (default: #{opts[:offset]})", Integer ) do |offset|
61
+ opts[:offset] = offset
62
+ end
127
63
 
128
64
  cmd.on("-h", "--help", "Prints this help") do
129
65
  puts cmd
@@ -137,26 +73,31 @@ class Tool
137
73
  pp opts
138
74
 
139
75
  puts "==> reading >#{opts[:file]}<..."
140
- punks = Image.read( opts[:file] )
76
+ punks = Image::Composite.read( opts[:file] )
141
77
 
142
78
 
143
79
  puts " setting zoom to #{opts[:zoom]}x" if opts[:zoom] != 1
144
- punks.zoom = opts[:zoom] ## note: always reset zoom even if 1
145
80
 
146
81
  ## make sure outdir exits (default is current working dir e.g. .)
147
82
  FileUtils.mkdir_p( opts[:outdir] ) unless Dir.exist?( opts[:outdir] )
148
83
 
149
84
  args.each_with_index do |arg,index|
150
85
  punk_index = arg.to_i
151
- punk_name = "punk-" + "%04d" % punk_index
86
+
87
+ punk = punks[ punk_index ]
88
+
89
+ punk_name = "punk-" + "%04d" % (punk_index + opts[:offset])
152
90
 
153
91
  ## if zoom - add x2,x4 or such
154
- punk_name << "x#{opts[:zoom]}" if opts[:zoom] != 1
92
+ if opts[:zoom] != 1
93
+ punk = punk.zoom( opts[:zoom] )
94
+ punk_name << "x#{opts[:zoom]}"
95
+ end
155
96
 
156
97
  path = "#{opts[:outdir]}/#{punk_name}.png"
157
- puts "==> (#{index+1}/#{args.size}) minting punk ##{punk_index}; writing to >#{path}<..."
98
+ puts "==> (#{index+1}/#{args.size}) minting punk ##{punk_index+opts[:offset]}; writing to >#{path}<..."
158
99
 
159
- punks[ punk_index ].save( path )
100
+ punk.save( path )
160
101
  end
161
102
 
162
103
  puts "done"
@@ -171,6 +112,18 @@ end ## module Cryptopunks
171
112
 
172
113
 
173
114
 
115
+
116
+ ### add more built-in (load on demand) design series / collections
117
+ DESIGNS_ORIGINAL = Cryptopunks::DesignSeries.new( "#{Cryptopunks.root}/config/original" )
118
+ DESIGNS_MORE = Cryptopunks::DesignSeries.new( "#{Cryptopunks.root}/config/more" )
119
+
120
+ ## all designs in one collections
121
+ DESIGNS = {}.merge( DESIGNS_ORIGINAL.to_h,
122
+ DESIGNS_MORE.to_h )
123
+
124
+
125
+
126
+
174
127
  ### add some convenience shortcuts
175
128
  CryptoPunks = Cryptopunks
176
129
  Punks = Cryptopunks
@@ -178,4 +131,10 @@ Punks = Cryptopunks
178
131
 
179
132
 
180
133
 
134
+ ###
135
+ # note: for convenience auto include Pixelart namespace!!! - why? why not?
136
+ include Pixelart
137
+
138
+
139
+
181
140
  puts Cryptopunks.banner # say hello
@@ -0,0 +1,147 @@
1
+ module Cryptopunks
2
+
3
+ ##################
4
+ ## 5 punk types
5
+ TYPES = [
6
+ { name: 'Alien', limit: 9 },
7
+ { name: 'Ape', limit: 24 },
8
+ { name: 'Zombie', limit: 88 },
9
+ { name: 'Female', limit: 3840 },
10
+ { name: 'Male', limit: 6039 },
11
+ ]
12
+
13
+
14
+ ###
15
+ ## categories used from:
16
+ ## https://cryptoslam.io/cryptopunks/checklist
17
+ ## see categories in urls e.g.
18
+ ## - cryptopunks/eyes/horned-rim-glasses
19
+ ## - cryptopunks/hair/peak-spike
20
+ ## - cryptopunks/emotion/smile
21
+ ## - etc.
22
+ ##
23
+
24
+ #######
25
+ ## 87 attributes / accessories
26
+ ##
27
+ ## note: does NOT include 5 punk types (that is, alien, ape, zombie, female, male)
28
+
29
+
30
+ ACCESSORY_TYPES = [
31
+ { name: 'Mouth', accessories: [ { name: 'Cigarette', limit: 961 },
32
+ { name: 'Pipe', limit: 317 },
33
+ { name: 'Vape', limit: 272 },
34
+ { name: 'Medical Mask', limit: 175 }]
35
+ },
36
+ { name: 'Nose', accessories: [ { name: 'Clown Nose', limit: 212 }]
37
+ },
38
+ {
39
+ name: 'Hair',
40
+ accessories: [ { name: 'Wild Blonde', limit: 144 },
41
+ { name: 'Wild Hair', limit: 447 },
42
+ { name: 'Dark Hair', limit: 157 },
43
+ { name: 'Stringy Hair', limit: 463 },
44
+ { name: 'Crazy Hair', limit: 414 },
45
+ { name: 'Messy Hair', limit: 460 },
46
+ { name: 'Mohawk', limit: 441 },
47
+ { name: 'Mohawk Thin', limit: 441 },
48
+ { name: 'Mohawk Dark', limit: 429 },
49
+ { name: 'Peak Spike', limit: 303 },
50
+ { name: 'Frumpy Hair', limit: 442 },
51
+ { name: 'Clown Hair Green', limit: 148 },
52
+ { name: 'Shaved Head', limit: 300 },
53
+ { name: 'Vampire Hair', limit: 147 },
54
+ { name: 'Red Mohawk', limit: 147 },
55
+ { name: 'Blonde Bob', limit: 147 },
56
+ { name: 'Straight Hair Dark', limit: 148 },
57
+ { name: 'Straight Hair', limit: 151 },
58
+ { name: 'Purple Hair', limit: 165 },
59
+ { name: 'Straight Hair Blonde', limit: 144 },
60
+ { name: 'Wild White Hair', limit: 136 },
61
+ { name: 'Half Shaved', limit: 147 },
62
+ { name: 'Pigtails', limit: 94 },
63
+ { name: 'Orange Side', limit: 68 },
64
+ { name: 'Do-rag', limit: 300 },
65
+ { name: 'Tiara', limit: 55 },
66
+ { name: 'Blonde Short', limit: 129 },
67
+ { name: 'Pink With Hat', limit: 95 },
68
+ { name: 'Beanie', limit: 44 },
69
+ { name: 'Headband', limit: 406 },
70
+ { name: 'Bandana', limit: 481 },
71
+ { name: 'Hoodie', limit: 259 },
72
+ { name: 'Top Hat', limit: 115 },
73
+ { name: 'Tassle Hat', limit: 178 },
74
+ { name: 'Cap', limit: 351 },
75
+ { name: 'Knitted Cap', limit: 419 },
76
+ { name: 'Cap Forward', limit: 254 },
77
+ { name: 'Police Cap', limit: 203 },
78
+ { name: 'Fedora', limit: 186 },
79
+ { name: 'Pilot Helmet', limit: 54 },
80
+ { name: 'Cowboy Hat', limit: 142 }]
81
+ },
82
+ {
83
+ name: 'Beard',
84
+ accessories: [{ name: 'Normal Beard', limit: 292 },
85
+ { name: 'Normal Beard Black', limit: 289 },
86
+ { name: 'Front Beard Dark', limit: 260 },
87
+ { name: 'Front Beard', limit: 273 },
88
+ { name: 'Shadow Beard', limit: 526 },
89
+ { name: 'Luxurious Beard', limit: 286 },
90
+ { name: 'Big Beard', limit: 146 },
91
+ { name: 'Chinstrap', limit: 282 },
92
+ { name: 'Mustache', limit: 288 },
93
+ { name: 'Muttonchops', limit: 303 },
94
+ { name: 'Handlebars', limit: 263 },
95
+ { name: 'Goat', limit: 295 }]
96
+ },
97
+ {
98
+ name: 'Ears',
99
+ accessories: [{ name: 'Earring', limit: 2459 }]
100
+ },
101
+ {
102
+ name: 'Eyes',
103
+ accessories: [{ name: 'Blue Eye Shadow', limit: 266 },
104
+ { name: 'Purple Eye Shadow', limit: 262 },
105
+ { name: 'Green Eye Shadow', limit: 271 },
106
+ { name: 'Welding Goggles', limit: 86 },
107
+ { name: 'VR', limit: 332 },
108
+ { name: '3D Glasses', limit: 286 },
109
+ { name: 'Clown Eyes Blue', limit: 384 },
110
+ { name: 'Clown Eyes Green', limit: 382 },
111
+ { name: 'Small Shades', limit: 378 },
112
+ { name: 'Regular Shades', limit: 527 },
113
+ { name: 'Big Shades', limit: 535 },
114
+ { name: 'Classic Shades', limit: 502 },
115
+ { name: 'Nerd Glasses', limit: 572 },
116
+ { name: 'Horned Rim Glasses', limit: 535 },
117
+ { name: 'Eye Mask', limit: 293 },
118
+ { name: 'Eye Patch', limit: 461 }]
119
+ },
120
+ {
121
+ name: 'Lips',
122
+ accessories: [{ name: 'Purple Lipstick', limit: 655 },
123
+ { name: 'Black Lipstick', limit: 617 },
124
+ { name: 'Hot Lipstick', limit: 696 } ]
125
+ },
126
+ {
127
+ name: 'Face',
128
+ accessories: [{ name: 'Spots', limit: 124 },
129
+ { name: 'Mole', limit: 644 }]
130
+ },
131
+ {
132
+ name: 'Neck',
133
+ accessories: [{ name: 'Choker', limit: 48 },
134
+ { name: 'Silver Chain', limit: 156 },
135
+ { name: 'Gold Chain', limit: 169 }]
136
+ },
137
+ { name: 'Cheeks', accessories: [{ name: 'Rosy Cheeks', limit: 128 }]
138
+ },
139
+ { name: 'Teeth', accessories: [{ name: 'Buck Teeth', limit: 78 }]
140
+ },
141
+ { name: 'Emotion', accessories: [{ name: 'Frown', limit: 261 },
142
+ { name: 'Smile', limit: 238 }]
143
+ }
144
+ ]
145
+
146
+
147
+ end # module Cryptopunks