cryptopunks 1.0.0 → 1.2.1

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,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