class C def initialize @size_x = 20 @size_y = 20 @dots = [] @sushis = [] end def dot!(loc) if 0 <= loc[0] && loc[0] < @size_x && 0 <= loc[1] && loc[1] < @size_y @dots += [loc] else raise "Out of boundary: #{loc}" end end def sushi!(loc) if 0 <= loc[0] && loc[0] < @size_x && 0 <= loc[1] && loc[1] < @size_y @sushis += [loc] else raise "Out of boundary: #{loc}" end end # Bresenham's algorithm def draw_line!(loc0, loc1) if loc0 == loc1 dot!(lot0) return end sushi!(loc0) sushi!(loc1) (x0, y0) = loc0 (x1, y1) = loc1 dx = (x1 - x0).abs dy = (y1 - y0).abs step_x = x0 == x1 ? 0 : x0 < x1 ? 1 : -1 step_y = y0 == y1 ? 0 : y0 < y1 ? 1 : -1 # step_y = dy == 0 ? 0 : dy < 0 ? -1 : 1 f = 0 if dx > dy y = y0 x0.step(x1, step_x).each do |x| if f > 0 y += step_y dot!([x, y]) f += 2*dy - 2*dx else dot!([x, y]) f += 2*dy end end else x = x0 y0.step(y1, step_y).each do |y| if f > 0 x += step_x dot!([x, y]) f += 2*dx - 2*dy else dot!([x, y]) f += 2*dx end end end rescue p [loc0, loc1] raise end def fill_rect!(loc0, loc1) (x0, y0) = loc0 (x1, y1) = loc1 dx = x1 - x0 dy = y1 - y0 step_x = dx < 0 ? -1 : 1 step_y = dy < 0 ? -1 : 1 x0.step(x1, step_x).each do |x| y0.step(y1, step_y) do |y| dot!([x, y]) end end end def to_a Array.new(@size_x) {|x| Array.new(@size_y) {|y| case [x, y] when *@sushis '🍣' when *@dots '⬛' else ' ' end }.join('') + '|' } end def to_s [ '--' * @size_x, *to_a(), '--' * @size_x, ].join("\n") end end c = C.new # c.draw_line!(*) # puts c # exit c.draw_line!([rand(20), rand(20)], [rand(20), rand(20)]) c.draw_line!([rand(20), rand(20)], [rand(20), rand(20)]) c.draw_line!([0, 0], [19, 0]) c.draw_line!([0, 0], [0, 19]) c.draw_line!([19, 19], [19, 0]) c.draw_line!([19, 19], [0, 19]) # c.fill_rect!([rand(20), rand(20)], [rand(20), rand(20)]) puts c.to_a