Skip to content

Instantly share code, notes, and snippets.

@ror3d
Last active August 29, 2015 14:19
Show Gist options
  • Save ror3d/2ba23845d65649c82ca8 to your computer and use it in GitHub Desktop.
Save ror3d/2ba23845d65649c82ca8 to your computer and use it in GitHub Desktop.
Generators for the jigsaw code puzzle challenge.
# Creates a grid of numbers, where each number is the minimum L2 (Manhattan) distance to
# the nearest zero in the grid.
# Called as
# $ ruby image_generator.rb _width_ [_height_ [_num_zeroes_ [_max_num_]]]
# width - the number of columns of the output
# height - defaults to width
# num_zeroes - maximum number of zeroes in the output
# max_num defaults to 9
require 'optparse'
w = ARGV[0].to_i
h = w
max = 999999
zeroes = 1
if ARGV.length > 1
h = ARGV[1].to_i
if ARGV.length > 2
zeroes = ARGV[2].to_i
if ARGV.length > 3
max = ARGV[3].to_i
end
end
end
def dist(a,b)
#a.zip(b).map {|l| (l[0]-l[1]).abs}.max
a.zip(b).map {|l| (l[0]-l[1]).abs}.reduce &:+
end
prng = Random.new
img = []
z_pos = []
zeroes.times do |i|
z_pos.push [prng.rand(w), prng.rand(h)]
end
h.times do |y|
img.push([])
w.times do |x|
img[y][x] = z_pos.map {|z| [max,(dist z,[x,y])].min}.min
end
line = img[y].map(&:to_s).join ' '
puts line
end
# Called as
# ruby puzzle_generator.rb [-o] [-r] [_n_different_connections_]
# -o - outputs pieces in order (rows); by default outputs them in randomized order
# -r - outputs pieces randomly rotated, except the first one
# n_different_connections - number of different connections to use. Defaults to log2(w*h)
#
# Reads from standard input a space/newline separated tiles map
$n_cTypes = nil
ordered = false
rotate = false
ARGV.each do |a|
if a == '-o'
ordered = true
elsif a == '-r'
rotate = true
else
$n_cTypes = ARGV[0].to_i if Integer(a) rescue $n_cTypes
end
end
w = nil
h = 0
mat = []
$rnd = Random.new
eof = false
until eof do
line = $stdin.gets
line = line.chomp unless line.nil?
if !line.nil? and line.length > 0
mat.push line.split(' ').map &:to_i
w = w ? ([w, mat.last.length].min) : mat.last.length
h+=1
else
eof = true
end
end
if $n_cTypes.nil? || $n_cTypes < 1
$n_cTypes = Math.log2(w*h).floor + 1
end
horz = []
vert = []
def getRandomConnection
rnd = $rnd
l = ('a'.ord + rnd.rand($n_cTypes)).chr
if rnd.rand(2) == 0
l = l.upcase
end
return l
end
h.times do |y|
horz.push []
vert.push []
w.times do |x|
horz.last.push getRandomConnection
vert.last.push getRandomConnection
end
end
pieces = []
positions = []
h.times do |y|
w.times do |x|
positions.push [x, y]
end
end
unless ordered
positions = positions.shuffle
end
positions.each do |x,y|
p = mat[y][x].to_s
#left = x > 0 ? 2 : 0
cn = []
cn.push (y > 0 ? vert[y-1][x].swapcase : nil)
cn.push (x < w-1 ? horz[y][x] : nil)
cn.push (y < h-1 ? vert[y][x] : nil)
cn.push (x > 0 ? horz[y][x-1].swapcase : nil)
if rotate and pieces.length > 0 # Rotate only after the first
cn.rotate! $rnd.rand(4)
end
left = cn[3] ? 2 : 0
p = cn[3] + " " + p if cn[3]
p = " "*left + cn[0] + "\n" + p if cn[0]
p = p + " " + cn[1] if cn[1]
p = p + "\n" + " "*left + cn[2] if cn[2]
p += "\n"
pieces.push p
end
pieces.each do |p|
puts p + "\n"
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment