# 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