Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- class Maze
- BREADCRUMBS = '.'
- WALKABLE = ' '
- WALL = 'X'
- DEAD_END = 'D'
- attr_reader :map, :coords
- def initialize(map)
- @map = map
- @coords = to_a
- end
- def draw_path
- coords.each_with_index do |row, y|
- row.each_with_index do |icon, x|
- @y, @x = y, x
- walk
- end
- end
- end
- def to_a
- rows.inject([]) do |board, row|
- board << row.split(//).inject([]) {|arr, icon| arr << icon}
- end
- end
- def to_s
- coords.inject('') do |maze, row|
- maze << "#{row.join}\n"
- end.gsub(DEAD_END, ' ')
- end
- def walk
- if current_position == WALKABLE
- coords[@y][@x] = walkable? ? BREADCRUMBS : DEAD_END
- end
- end
- def rows
- @rows ||= map.split("\n")
- end
- def width
- rows.first.size
- end
- def walkable?
- nearby_coords.select do |position|
- [WALL, DEAD_END].include? get(position)
- end.size < 3
- end
- def current_position
- get [@y, @x]
- end
- def get(coord)
- coords[coord.first][coord.last]
- end
- def nearby_coords
- [[@y-1, @x], [@y+1, @x], [@y, @x-1], [@y, @x+1]]
- end
- end
- require 'rspec'
- map = <<-MAZE
- XXXXXXXXXXXX
- # XXX X o
- XXX X X X XX
- XX XX
- XXXXXXXXXXXX
- MAZE
- solution = <<-MAZE
- XXXXXXXXXXXX
- #...XXX X..o
- XXX.X X X.XX
- XX .......XX
- XXXXXXXXXXXX
- MAZE
- describe Maze do
- subject { Maze.new(map) }
- it 'assings map' do
- subject.map.should == map
- end
- describe '#rows' do
- it 'splits map in rows' do
- subject.rows.size.should == 5
- end
- end
- describe '#width' do
- it 'returns the map width' do
- subject.width.should == 12
- end
- end
- describe '#to_a' do
- it 'returns bidimensional array' do
- subject.to_a.should be_an(Array)
- subject.to_a.first.should be_an(Array)
- end
- end
- describe '#to_s' do
- it 'returns a string' do
- subject.to_s.should be_a(String)
- end
- context 'when path has not been walked yet' do
- it 'returns original map' do
- subject.to_s.should == map
- end
- end
- end
- describe '#coords' do
- it 'returns the maze in array format' do
- subject.coords.should == subject.to_a
- end
- end
- describe '#get' do
- it 'wraps array access to coords' do
- subject.get([1,2]).should == subject.coords[1][2]
- end
- end
- describe '#current_position' do
- it 'should return the icon in the current position' do
- subject.instance_eval { @x, @y = 11, 1 }
- subject.current_position.should == 'o'
- end
- end
- describe '#nearby_coords' do
- it 'returns an array of coordinates' do
- subject.instance_eval { @x, @y = 2, 1}
- subject.nearby_coords.should =~ [[0, 2], [2, 2], [1, 1], [1,3]]
- end
- end
- describe '#walkable?' do
- context 'when the coord is surrounded by 3 or more walls/dead ends' do
- it 'is false' do
- subject.instance_eval {@x, @y = 2, 3}
- subject.should_not be_walkable
- end
- end
- context 'when the coord is surrounded by less than 3 walls/dead ends' do
- it 'is true' do
- subject.instance_eval {@x, @y = 1, 1}
- subject.should be_walkable
- end
- end
- end
- describe '#walk' do
- context 'when the coord is walkable' do
- it 'should change it to breadcrumbs icon' do
- subject.instance_eval { @x, @y = 1, 1 }
- subject.walk
- subject.get([1, 1]).should == '.'
- end
- end
- end
- describe '#draw_path' do
- it 'should draw the path to exit' do
- subject.draw_path
- subject.to_s.should == solution
- end
- end
- end
- puts Maze.new(map).tap {|bc| bc.draw_path}.to_s
- require 'benchmark'
- Benchmark.bm do |bm|
- bm.report 'Andrea Longhi' do
- 10000.times { Maze.new(map).draw_path }
- end
- end
Add Comment
Please, Sign In to add comment