Мариян обнови решението на 02.12.2015 00:48 (преди около 9 години)
+module TurtleGraphics
+ class Turtle
+ ORIENTATIONS = %i(left up right down)
+ MOVE_VECTORS = [{x: -1, y: 0}, {x: 0, y: -1}, {x: 1, y: 0}, {x: 0, y: 1}]
+
+ def initialize(rows, columns)
+ @canvas_size = {x: columns, y: rows}
+ @orientation = ORIENTATIONS.index :right
+ @position = {x: 0, y: 0}
+ @turtle_steps = Array.new(rows) { Array.new(columns, 0) }
+ @turtle_steps[0][0] = 1
+ end
+
+ def draw(canvas = nil, &block)
+ instance_eval &block if block_given?
+ return @turtle_steps.dup if canvas.nil?
+ max = @turtle_steps.flatten.max
+ intensities = @turtle_steps.map do |row|
+ row.map { |times_visited| times_visited.to_f / max }
+ end
+ canvas.draw(intensities)
+ end
+
+ def move
+ [:x, :y].each do |axis|
+ @position[axis] += MOVE_VECTORS[@orientation][axis]
+ @position[axis] += @canvas_size[axis]
+ @position[axis] %= @canvas_size[axis]
+ end
+ @turtle_steps[@position[:y]][@position[:x]] += 1
+ end
+
+ def turn_left
+ @orientation += ORIENTATIONS.size - 1
+ @orientation %= ORIENTATIONS.size
+ end
+
+ def turn_right
+ @orientation += 1
+ @orientation %= ORIENTATIONS.size
+ end
+
+ def spawn_at(row, column)
+ @position[:x], @position[:y] = column, row
+ @turtle_steps[0][0] = 0
+ @turtle_steps[row][column] = 1
+ end
+
+ def look(orientation)
+ @orientation = ORIENTATIONS.index orientation
+ end
+ end
+
+ module Canvas
+ class ASCII
+ def initialize(symbols)
+ @symbols = symbols
+ end
+
+ def draw(intensities)
+ intensities.map do |row|
+ row.map { |intensity| @symbols[to_index(intensity)] }.join
+ end.join "\n"
+ end
+
+ private
+ def to_index(intensity)
+ return 0 if intensity == 0
+ range = 1.0 / (@symbols.size - 1)
+ quotient = intensity / range
+ unless quotient % 1 == 0
+ quotient += 1
+ end
+ quotient.to_i
+ end
+ end
+
+ class HTML
+ def initialize(pixel_size)
+ @pixel_size = pixel_size
+ end
+
+ def draw(intensities)
+ <<-HTML.gsub(/^ {10}/, '').chomp
+ <!DOCTYPE html>
+ <html>
+ <head>
+ <title>Turtle graphics</title>
+
+ <style>
+ table {
+ border-spacing: 0;
+ }
+
+ tr {
+ padding: 0;
+ }
+
+ td {
+ width: #{@pixel_size}px;
+ height: #{@pixel_size}px;
+
+ background-color: black;
+ padding: 0;
+ }
+ </style>
+ </head>
+ <body>
+ <table>
+ #{print_rows(intensities)}
+ </table>
+ </body>
+ </html>
+ HTML
+ end
+
+ private
+ def print_rows(intensities)
+ intensities.map do |row|
+ <<-HTML.gsub(/^ {12}/, '').chomp
+ <tr>
+ #{print_columns(row)}
+ </tr>
+ HTML
+ end.join "\n"
+ end
+
+ def print_columns(row)
+ row.map do |column|
+ ' <td style="opacity: %.2f"></td>' % column
+ end.join "\n"
+ end
+ end
+ end
+end