Георги обнови решението на 02.12.2015 02:23 (преди около 9 години)
+module TurtleGraphics
+ class Turtle
+ def initialize(rows, columns)
+ @rows = rows
+ @columns = columns
+ @pixel_map = Array.new(rows) { Array.new(columns) { 0 } }
+ @current_position = [0, 0]
+ @orientations = [:right, :down, :left, :up]
+ @orientation_index = 0
+ @directions = {:left => [0, -1], :up => [-1, 0] }
+ @directions[:right] = [0, 1]
+ @directions[:down] = [1, 0]
+
+ mark_position_visited
+ end
+
+ def draw(canvas = nil, &block)
+ self.instance_eval(&block)
+
+ drawing = canvas.draw(@pixel_map) if canvas.respond_to? :draw
+ return drawing if drawing
+ @pixel_map
+ end
+
+private
+ def turn_right
+ @orientation_index = (@orientation_index + 1) % @orientations.size
+ end
+
+ def turn_left
+ @orientation_index = (@orientation_index - 1) % @orientations.size
+ end
+
+ def orientation
+ @orientations[@orientation_index]
+ end
+
+ def move
+ from_row = @current_position.first
+ from_column = @current_position.last
+
+ to_row = from_row + @directions[orientation].first
+ to_column = from_column + @directions[orientation].last
+
+ to_row = 0 if to_row == @rows
+ to_column = 0 if to_column == @columns
+
+ @current_position = [to_row, to_column]
+
+ mark_position_visited
+
+ @current_position
+ end
+
+ def spawn_at(row, column)
+ @current_position = [row, column]
+ mark_position_visited
+ end
+
+ def look(direction)
+ @direction = direction
+ end
+
+ def mark_position_visited
+ row = @current_position.first
+ column = @current_position.last
+ @pixel_map[row][column] += 1
+ end
+
+ def to_s
+ @pixel_map.each { |row| p row }
+ end
+
+ end #end of class Turtle
+
+ module Canvas
+ class ASCII
+ def initialize(symbols)
+ @symbols = symbols
+ end
+
+ def symbol_for_pixel(pixel)
+ number_of_symbols = @symbols.size
+ approximate_index = (number_of_symbols - 1) * pixel
+ p "Appr index = #{approximate_index}"
+
+ index = approximate_index.round
+ p "Index = #{index}"
+ @symbols[index]
+ end
+
+ def draw(pixel_map)
+ highest_intensity = pixel_map.flatten.max
+ intensity_map = pixel_map.each do | row |
+ row.map! { | pixel | pixel.to_f / highest_intensity.to_f }
+ end
+ intensity_map.each do | row |
+ row.map! { | pixel | symbol_for_pixel(pixel) }
+ end
+
+ intensity_map
+ end
+
+ end #of class ASCII
+
+ class HTML
+ def initialize(cell_size)
+ @cell_size = cell_size
+ end
+
+ def html_document(pixel_map)
+ "<!DOCTYPE html>\n"\
+ "<html>\n"\
+ "#{html_head}"\
+ "#{html_body(pixel_map)}"\
+ "</html>"
+ end
+
+ def html_head
+ "<head>\n"\
+ " <title>Turtle graphics</title>\n\n"\
+ "#{html_style}\n"\
+ "</head>\n"
+ end
+
+ def html_style
+ " <style>\n"\
+ " table {\n"\
+ " border-spacing: 0;\n }\n\n"\
+ " tr {\n padding: 0;\n }\n\n"\
+ " td {\n"\
+ " width: #{@cell_size}px;\n"\
+ " height: #{@cell_size}px;\n\n"\
+ " background-color: black;\n"\
+ " padding: 0;\n }\n"\
+ " </style>"
+ end
+
+ def html_body(pixel_map)
+ "<body>\n"\
+ "#{construct_html_table(pixel_map)}"\
+ "</body>\n"
+ end
+
+ def html_cell(opacity)
+ " <td style=\"opacity: #{format('%.2f', opacity)}\"></td>"
+ end
+
+ def html_row(html_cells)
+ " <tr>\n"\
+ "#{html_cells.join("\n")}\n"\
+ " </tr>"
+ end
+
+ def html_table(html_rows)
+ " <table>\n"\
+ "#{html_rows.join("\n")}\n"\
+ " </table>\n"
+ end
+
+ def construct_html_table(pixel_map)
+
+ highest_intensity = pixel_map.flatten.max
+ intensity_map = pixel_map.each do | row |
+ row.map! { | pixel | pixel / highest_intensity }
+ end
+
+ intensity_map.each do | row |
+ row.map! { | pixel | html_cell(pixel) }
+ end
+
+ html_rows = intensity_map.map { | row | html_row(row) }
+
+ html_table(html_rows)
+ end
+
+ def draw(pixel_map)
+ html_document(pixel_map)
+ end
+ end #of class HTML
+ end #of module Canvas
+end #of module TurtleGraphics