From: Martin Boese Date: 2009-03-17T02:04:13+09:00 Subject: Re: [QUIZ] Sliding Puzzle (#196) --=-Sa0Dp6WW86syGEDOWmu3 Content-Type: text/plain Content-Transfer-Encoding: 7bit My small solution attached. It will create an 8-puzzle by default, but can do n-puzzle if you specify width and height as parameters. Then you can shuffle it with 's' key - it will make 100 random moves. Everything else remains basic... so the party when solved ;-) Martin On Sat, 2009-03-14 at 00:49 +0900, Daniel Moore wrote: > -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- > > The three rules of Ruby Quiz: > > 1. Please do not post any solutions or spoiler discussion for this > quiz until 48 hours have elapsed from the time this message was > sent. > > 2. Support Ruby Quiz by submitting ideas and responses > as often as you can! Visit: > > 3. Enjoy! > > Suggestion: A [QUIZ] in the subject of emails about the problem > helps everyone on Ruby Talk follow the discussion. Please reply to > the original quiz message, if you can. > > -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- > > ## Sliding Puzzle (#196) > > Bienvenidos fellow Rubyists, > > This weeks quiz will be to create and implement a [sliding puzzle][1]. > The puzzle must be playable from keyboard input. The program will > generate a puzzle in a random configuration and the puzzle generated > must be solvable. You may create either the 8-puzzle or the 15-puzzle. > You may include a mode that will automatically solve the puzzle or > present a hint. > > The puzzle must throw a small party when solved. > > Bonus: Have the puzzle be displayed as an ascii art image that needs > to be arranged instead of simple numbers. > > [1]: http://en.wikipedia.org/wiki/Fifteen_puzzle > > > Have Fun! --=-Sa0Dp6WW86syGEDOWmu3 Content-Disposition: attachment; filename="spuzzle.rb" Content-Type: application/x-ruby; name="spuzzle.rb" Content-Transfer-Encoding: 7bit class Puzzle def initialize(x,y) @board = mkboard(x,y) @x, @y = x, y end def mkboard(x,y) board = Array.new(x*y) { |e| e+1 } board[-1] = nil board end def put(x,y,c) @board[y*@y+x] = c end def get(x,y) @board[y*@y+x] end # index -> coordinates def i2c(idx) [(idx % @y), (idx / @y)] end def dump (0..(@y-1)).to_a.each { |y| (0..(@x-1)).to_a.each { |x| $stdout.print get(x,y) ? "%3d" % get(x,y) : ' ' }; puts } end def solved? @board == mkboard(@x,@y) && @moved end def move(direction) x,y = i2c(@board.index(nil)) fx, fy = x,y case direction when 'u' fy = y+1 when 'd' fy = y-1 when 'l' fx = x+1 when 'r' fx = x-1 end return if ((fx >= @x) || (fx < 0) || (fy >= @y) || (fy < 0)) return if ((fx == x) && (fy == y)) @moved = true put(x,y, get(fx,fy)) put(fx,fy,nil) end def shuffle 100.times { move 'udlr'[(rand*4).to_i].chr } end end p = Puzzle.new((ARGV[0] || 3).to_i,(ARGV[1] || 3).to_i) while (!p.solved?) do p.dump print "Use (U)p, (D)own, (L)eft, (R)ight, (S)huffle, (Q)uit: " command = $stdin.gets[0].chr.downcase p.shuffle if command == 's' exit if command == 'q' p.move command end puts 10.times { $stdout.print '*'; sleep 0.1; $stdout.flush } puts " You won!\n" --=-Sa0Dp6WW86syGEDOWmu3--