require ‘chunky_png’
class Color
def initialize(color_table=nil)
@color_table = color_table || [1, 0]
end

def rgb
colors = [
[[255,192,192], [255,0,0], [192,0,0]], # Red
[[255,255,192], [255,255,0], [192,192,0]], # Yellow
[[192,255,192], [0,255,0], [0,192,0]], # Green
[[192,255,255], [0,255,255], [0,192,192]], # Cyan
[[192,192,255], [0,0,255], [0,0,192]], # Blue
[[255,192,255], [255,0,255], [192,0,192]], # Magenta
]
colors[@color_table[1]][@color_table[0]]
end

def push_color
@color_table[0] = (@color_table[0] + 1) % 3
rgb
end

def write_color
@color_table[0] = (@color_table[0] + 2) % 3
@color_table[1] = (@color_table[1] + 5) % 6
rgb
end
end

current_color = Color.new
piet_painting = []

def draw_block(piet_painting, current_color,size,num)
block = Array.new(12) { Array.new(12) { Array.new(3, 0) } }
if num != 0
old_push_color = current_color.push_color
current_color.write_color

block.each_index do |i|
block[i].each_index do |j|
block[i][j] = current_color.rgb
end
end
block[0][0] = old_push_color
size += 1
else
block.each_index do |i|
block[i].each_index do |j|
block[i][j] = current_color.rgb
end
end
end

pix_lft = 144 - size
div = pix_lft / 12
rem = pix_lft % 12

if div != 0
block[(12-div)…-1].each_index do |i|
block[(12-div)…-1][i].each_index do |j|
block[(12-div)+i][j] = [0,0,0]
end
end
end
block[(11-div)…-1].each_index do |i|
block[(11-div)…-1][i][0…rem].each_index do |j|
block[(11-div)+i][j] = [0,0,0]
end
end
pos_y = 12 * num
pos_x = 0
piet_painting[pos_x…(pos_x+12)].each_index do |i|
piet_painting[pos_x…(pos_x+12)][i][pos_y…(pos_y+12)].each_index do |j|
piet_painting[pos_x+i][pos_y+j] = block[i][j]
end
end
end

def draw_end(piet_painting, current_color, num)
block = Array.new(12) { Array.new(5) { Array.new(3, 255) } }

old_push_color = current_color.push_color
block[0][0] = old_push_color
block[0][1] = current_color.write_color
block[0…2].each_index do |i|
block[i][3] = [0, 0, 0]
end
block[1][1] = [0, 0, 0]
block[2][0] = [0, 0, 0]
block[2][4] = [0, 0, 0]
block[3][1…4].each_index do |i|
block[3][i + 1] = [0, 0, 0]
end
c_color = current_color.write_color
block[2][1…4].each_index do |i|
block[2][i + 1] = c_color
end
pos_y = 12 * num
pos_x = 0
piet_painting[pos_x…(pos_x+12)].each_index do |i|
piet_painting[pos_x…(pos_x+12)][i][pos_y…(pos_y+5)].each_index do |j|
piet_painting[pos_x+i][pos_y+j] = block[i][j]
end
end
end

# if painting_len < 390
# # plato_painting = Array.new(12 * painting_len) { Array.new(3, 0) }
# plato_painting = Array.new(12) { Array.new(painting_len) { Array.new(3, 0) } }
# plato_painting[0…12].map! { |row| row[0…painting_len] = piet_painting }
# image = MiniMagick::Image.read(plato_painting.flatten.join(“\n”))
# # image = MiniMagick::Image.new(“xc:white”)
# image.format(“png”)
# # image.from_array(plato_painting, format: ‘rgb’)
# image.write(‘plato_code.png’)
# end
message = ‘Let life be beautiful like summer flowers and death like autumn leaves.’
painting_len = message.length * 12 + 5
piet_painting = Array.new(12) { Array.new(painting_len) { Array.new(3, 0) } }
i = 0
message.chars.each_with_index do |char|
draw_block(piet_painting, current_color, char.ord, i)
i += 1
end
draw_end(piet_painting, current_color, i)
data = ChunkyPNG::Image.from_rgb_stream(painting_len, 12, piet_painting.flatten.pack(‘C*’))
data.save(‘poem.png’)
针对上面的代码写个piet编译器 The hard part is obviously reading the images and calculating the transitions, but even that should be a piece of cake with the help of the libraries.