Анджелин обнови решението на 28.11.2015 18:47 (преди около 9 години)
+module TurtleGraphics
+ class Point
+ attr_accessor :x
+ attr_accessor :y
+
+ def initialize(x, y)
+ @x = x
+ @y = y
+ end
+
+ def next(direction)
+ case direction
+ when :up then Point.new(@x - 1, @y)
+ when :right then Point.new(@x, @y + 1)
+ when :down then Point.new(@x + 1, @y)
+ when :left then Point.new(@x, @y - 1)
+ end
+ end
+ end
+
+
+ class Turtle
+ DIRECTIONS = [:up, :right, :down, :left]
+
+ attr_reader :canvas
+
+ def initialize(rows, columns)
+ @rows = rows
+ @columns = columns
+ @spawned = false
+
+ init_canvas()
+ look(:right)
+ end
+
+ def init_canvas()
+ @canvas = []
+ @rows.times { @canvas << Array.new(@columns, 0) }
+ end
+
+ def draw(drawer = nil, &block)
+ instance_eval &block
+
+ return @canvas unless drawer
+ drawer.to_canvas(@canvas)
+ end
+
+ def move()
+ unless @spawned
+ spawn_at(0, 0)
+ end
+
+ next_position = @position.next(@looks_at)
+ next_position.x %= @rows
+ next_position.y %= @columns
+
+ spawn_at(next_position.x, next_position.y)
+ end
+
+ def turn_left()
+ look(DIRECTIONS[DIRECTIONS.index(@looks_at) - 1])
+ end
+
+ def turn_right()
+ look(DIRECTIONS[(DIRECTIONS.index(@looks_at) + 1) % DIRECTIONS.size])
+ end
+
+ def spawn_at(row, column)
+ @spawned = true
+ @position = Point.new(row, column)
+ @canvas[row][column] += 1
+ end
+
+ def look(orientation)
+ unless (DIRECTIONS.include? orientation)
+ raise ArgumentError, "'#{orientation}' is not a valid direction."
+ end
+
+ @looks_at = orientation
+ end
+ end
+
+ module Canvas
+ class ASCII
+ def initialize(symbols)
+ @symbols = symbols
+ end
+
+ def to_canvas(canvas)
+ asci = ""
+ canvas.each do |row|
+ row.each { |cell| asci += drawer.symbols[cell] }
+ asci += "\n"
+ end
+
+ asci
+ end
+ end
+
+ class HTML
+ HEADER = '<!DOCTYPE html><html><head>' \
+ '<title>Turtle graphics</title>%s</head>'
+
+ CSS = '<style>table {border-spacing: 0;} tr{padding: 0;}' \
+ 'td {width: %spx;height: %spx;background-color: black;' \
+ 'padding: 0;}</style>'
+
+ ENTRY = '<td style="opacity: %s"></td>'
+
+
+ def initialize(td_size)
+ @document = HEADER % (CSS % [td_size, td_size])
+ end
+
+ def to_canvas(canvas)
+ @document += '<body><table>'
+
+ canvas.each do |row|
+ @document += '<tr>'
+
+ row.each do |cell|
+ @document += ENTRY % format('%.2f', (cell / row.max rescue 0))
+ end
+ @document += '</tr>'
+ end
+
+ @document += '</table></body></html>'
+ end
+ end
+ end
+end