def get_bitmap a = <= 0 and y >= 0 and $bmp[y][x] != "o" and $bmp[y][x] != "*" end def fill_step(meth) x,y = meth == :stack ? $queue.pop : $queue.shift if legal(x,y) fill_cell(x, y) [[x-1,y], [x,y-1], [x,y+1], [x+1, y]].each do |i,j| $queue.push [i,j] if legal(i,j) end end end def fill_cell(x, y) cfill(y, x, "#7777dd") $bmp[y][x] = "*" end def cfill(col, row, c) $canvas.fill c $canvas.rect :left => row*30, :right => (row+1)*30, :top => col*30, :bottom => (col+1)*30 $canvas.show end def reset_grid $bmp = get_bitmap $bmp.each_with_index {|row, j| row.each_with_index {|cell, i| c = cell == "o" ? "#111166" : "#eeeecc" cfill(j, i, c) } } $queue = [] end def run_animation(meth) $running ? return : $running = true reset_grid x, y = rand(20), rand(20) while $bmp[y][x] != "." x, y = rand(20), rand(20) end $queue.push [x, y] @anim = animate(20) do if $queue.empty? @anim.stop $running = false else fill_step(meth) end end end Shoes.app :width => 600, :height => 700, :resizable => false, :title => "Floodfill" do $canvas = image 600, 601, :top => 0, :left => 0 reset_grid stack :height => 79, :top => 620 do flow do button("Stack") { run_animation(:stack) } button("Queue") { run_animation(:queue) } button("Clear") { reset_grid } button("Quit") { quit } end end end