# Maze Maker
# a shoes app to make mazes
# using the "Hunt and Kill" algorithm
# as described here:
# http://www.astrolog.org/labyrnth/algrithm.htm
#

s = 40 # size of cell
cw = 20 # cells wide
ch = 10 # cells high
e = s / 4 # "edge" 

Shoes.app( :width => s * cw,
           :height => s * ch ) do

  background gradient(maroon, black)

  @cursor = image do
    nostroke
    fill white
    oval 0,0,s,s
  end


  @unvisited = []
  (0...cw).each { |x|
    (0...ch).each { |y| 
      @unvisited << [x, y]
    } 
  }
  @visited = []
  @noadj = []

  def find_unvisited_adjacent(last)
    x, y = last
    avail = []
    @unvisited.each_with_index do | e, i |
      if ((e[0] - x).abs + (e[1] - y).abs) == 1
        avail << i
      end
    end
    if avail.length > 0
      avail[rand(avail.length)]
    end
  end

  @current = @unvisited.delete_at(rand(@unvisited.length))

  @a = animate 24 do
    @cursor.move @current[0] * s , @current[1] * s
    @next = nil
    adj = find_unvisited_adjacent(@current)
    if adj
      @next = @unvisited.delete_at(adj)
      @cursor.move( @next[0] * s, @next[1] * s )
      the_left = [ @current[0], @next[0] ].min 
      the_right = [ @current[0], @next[0]].max
      the_top = [ @current[1], @next[1] ].min
      the_bottom = [ @current[1], @next[1]].max
      the_width = the_right - the_left + 1
      the_height = the_bottom - the_top + 1
      fill sandybrown
      nostroke
      rect(the_left * s + e, the_top * s + e, 
           the_width * s - 2 * e, the_height * s - 2 * e, 
           (s - 2 * e)/2)
      @visited << @current
      @current = @next
    else
      @noadj << @current
      @current = @visited.delete_at(rand(@visited.length))
    end
    if @unvisited.length == 0
      @a.stop
      @cursor.remove
    end
  end
  click do
    @a.stop
  end

end
