secret
Last active

  • Download Gist
ChristianKnappskog_Maze.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
class Maze
attr_reader :maze
HEIGHT = 13
WIDTH = 38
def initialize(maze_as_string)
@maze = Array.new(HEIGHT)
parse(maze_as_string)
solve
end
def solvable?
symbol_is_on_path?("A")
symbol_is_on_path?("B")
end
def steps
steps=0
y=0
while(y<HEIGHT) do
x=0
while(x<WIDTH) do
if @maze[y][x] == " "
steps+=1
end
x+=1
end
y+=1
end
unless steps==0
steps+=1 # For the final step onto finish
end
return steps
end
def parse(maze_as_string)
i=0
maze_as_string.each do |line|
@maze[i] = line.chars.to_a
i+=1
end
end
def solve
while(find_and_fill_dead_ends!=0) do
find_and_fill_dead_ends
end
end
def symbol_is_on_path?(symbol)
location = find_symbol(symbol)
return true if @maze[location[0]+1][location[1]] == " "
return true if @maze[location[0]-1][location[1]] == " "
return true if @maze[location[0]][location[1]+1] == " "
return true if @maze[location[0]][location[1]-1] == " "
return false
end
def find_symbol(symbol)
symbol_position = []
y=0
while(y<HEIGHT) do
x=0
while(x<WIDTH) do
symbol_position = [y, x] if @maze[y][x] == symbol
x+=1
end
y+=1
end
return symbol_position
end
def find_and_fill_dead_ends
y=0
filled_spaces = 0
HEIGHT.times do
x=0
WIDTH.times do
filled_spaces+=1 if fill_if_dead_end?(y, x)
x+=1
end
y+=1
end
return filled_spaces
end
def fill_if_dead_end?(y, x)
if @maze[y][x] == " "
wall_count = 0
wall_count += 1 if @maze[y-1][x] == "#"
wall_count += 1 if @maze[y+1][x] == "#"
wall_count += 1 if @maze[y][x+1] == "#"
wall_count += 1 if @maze[y][x-1] == "#"
if wall_count >= 3
@maze[y][x] = "#"
return true
end
end
end
def to_s
y=0
HEIGHT.times do
x=0
WIDTH.times do
print @maze[y][x]
x+=1
end
y+=1
end
end
end
ChristianKnappskog_Maze_spec.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
require 'spec'
require 'Maze'
 
MAZE1 = %{#####################################
# # # #A # # #
# # # # # # ####### # ### # ####### #
# # # # # # # # #
# ##### # ################# # #######
# # # # # # # # #
##### ##### ### ### # ### # # # # # #
# # # # # # B# # # # # #
# # ##### ##### # # ### # # ####### #
# # # # # # # # # # # #
# ### ### # # # # ##### # # # ##### #
# # # # # # #
#####################################}
# Maze 1 should SUCCEED
 
MAZE2 = %{#####################################
# # # # # #
# ### ### # ########### ### # ##### #
# # # # # # # # # #
# # ###A##### # # # # ### ###########
# # # # # # # # #
####### # ### ####### # ### ####### #
# # # # # # # #
# ####### # # # ####### # ##### # # #
# # # # # # # # # # #
# ##### # # ##### ######### # ### # #
# # # # #B#
#####################################}
 
# Maze 2 should SUCCEED
 
MAZE3 = %{#####################################
# # # # #
# ### # ####### # # # ############# #
# # # # # # # # # #
### ##### ### ####### # ##### ### # #
# # # # A # # # # #
# ######### ##### # ####### ### ### #
# ### # # # # #
# ### ### ####### ####### # # # # ###
# # # # # #B# # # # # # #
# # # ##### ### # # # # ### # ##### #
# # # # # #
#####################################}
# Maze 3 should FAIL
 
describe "Maze" do
context "when being initialized" do
before(:each) do
@maze = Maze.new(MAZE1)
end
it "should take a string as a parameter" do
end
it "should have a method called parse" do
@maze.should respond_to(:parse)
end
it "should contain the maze as an array" do
@maze.should respond_to(:maze)
@maze.maze.should be_kind_of(Array)
end
it "should be a todimentional array" do
@maze.maze[0].should respond_to("[]")
end
end
context "to rule out single dead ends" do
before(:each) do
@maze = Maze.new(MAZE1)
end
it "should fill in the first dead end" do
@maze.fill_if_dead_end?(1,1)
@maze.maze[1][1].should match("#")
end
it "should fill in an opposite dead end" do
@maze.fill_if_dead_end?(3,3)
@maze.maze[3][3].should match("#")
end
 
end
context "to find all first-level dead ends" do
before(:each) do
@maze = Maze.new(MAZE1)
end
it "should call a method to loop through all characters" do
@maze.find_and_fill_dead_ends
end
it "should fill in dead ends" do
@maze.find_and_fill_dead_ends
@maze.maze[1][1].should match("#")
@maze.maze[3][3].should match("#")
end
it "should pass the koordinates on to fill_if_dead_end?" do
@maze.should_receive(:fill_if_dead_end?).exactly(494).times
@maze.find_and_fill_dead_ends
end
end
context "to find start and ending points" do
before(:each) do
@maze1 = Maze.new(MAZE1)
@maze2 = Maze.new(MAZE2)
end
it "should find the starting-point" do
@maze1.find_symbol("A").should eql([1,13])
end
it "should find starting point of other mazes as well" do
@maze2.find_symbol("A").should eql([4,7])
end
it "should find the end point of both mazes" do
@maze1.find_symbol("B").should eql([7,23])
@maze2.find_symbol("B").should eql([11,35])
end
end
context "to verify that both a start and end-point are on the solvable path" do
before(:each) do
@maze1 = Maze.new(MAZE1)
end
it "start should have a blank neighbour after being saved" do
@maze1.solve
@maze1.find_symbol("A").should eql([1,13])
@maze1.maze[1][14].should eql(" ")
end
it "should check to see if both start and finish is on the path" do
@maze1.symbol_is_on_path?("A").should be_true
@maze1.symbol_is_on_path?("B").should be_true
end
it "should be solvable if both A and B is on the path" do
@maze1.solvable?.should be_true
end
end
context "valid mazes" do
it "should work" do
Maze.new(MAZE1).solvable?.should be_true
Maze.new(MAZE2).solvable?.should be_true
end
it "should return number of steps to end of maze" do
Maze.new(MAZE1).steps.should eql(44)
Maze.new(MAZE2).steps.should eql(75)
end
end
context "invalid mazes" do
it "should be unsolvable" do
Maze.new(MAZE3).solvable?.should be_false
end
it "should return 0 steps for invalid mazes" do
Maze.new(MAZE3).steps.should eql(0)
end
end
end

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.