maze-solver 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.coveralls.yml +1 -0
- data/.travis.yml +11 -0
- data/Gemfile +4 -0
- data/README.md +10 -6
- data/Rakefile +27 -4
- data/bin/maze-solver +1 -1
- data/lib/maze_solver.rb +9 -3
- data/lib/maze_solver/version.rb +1 -1
- data/spec/maze_solver_spec.rb +121 -0
- data/spec/spec_helper.rb +3 -1
- metadata +6 -6
- data/spec/maze_spec.rb +0 -106
- data/spec/test.maze +0 -7
data/.coveralls.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
service_name: travis-ci
|
data/.travis.yml
ADDED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Maze Solver
|
1
|
+
# Maze Solver [](https://travis-ci.org/johnsyweb/ruby_maze_solver) [](http://badge.fury.io/rb/maze-solver) [](https://gemnasium.com/johnsyweb/ruby_maze_solver) [](https://codeclimate.com/github/johnsyweb/ruby_maze_solver) [](https://coveralls.io/r/johnsyweb/ruby_maze_solver?branch=master)
|
2
2
|
|
3
3
|
Written as an exercise in applying Ruby, this project solves mazes:
|
4
4
|
|
@@ -24,19 +24,23 @@ Written as an exercise in applying Ruby, this project solves mazes:
|
|
24
24
|
|
25
25
|
## Installation
|
26
26
|
|
27
|
+
Maze Solver is available from
|
28
|
+
[RubyGems.org](https://rubygems.org/gems/maze-solver). Installation is simply:
|
29
|
+
|
27
30
|
$ gem install maze-solver
|
28
31
|
|
29
32
|
## Usage
|
30
33
|
|
31
|
-
maze-solver filename start_x start_y end_x end_y
|
34
|
+
$ maze-solver filename start_x start_y end_x end_y
|
32
35
|
|
33
36
|
## Contributing
|
34
37
|
|
35
38
|
1. Fork it
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
39
|
+
1. Create your feature branch (`git checkout -b my-new-feature`)
|
40
|
+
1. Commit your changes (`git commit -am 'Add some feature'`)
|
41
|
+
1. Push to the branch (`git push origin my-new-feature`)
|
42
|
+
1. Ensure the tests pass for all Rubies in [`.travis.yml`](https://github.com/johnsyweb/ruby_maze_solver/blob/master/.travis.yml)
|
43
|
+
1. Create new Pull Request
|
40
44
|
|
41
45
|
## Thanks
|
42
46
|
|
data/Rakefile
CHANGED
@@ -1,6 +1,29 @@
|
|
1
|
-
|
2
|
-
require "rspec/core/rake_task"
|
1
|
+
# encoding: utf-8
|
3
2
|
|
4
|
-
|
3
|
+
require 'bundler/gem_tasks'
|
4
|
+
require 'rspec/core/rake_task'
|
5
5
|
|
6
|
-
|
6
|
+
RSpec::Core::RakeTask.new('spec')
|
7
|
+
task default: [:spec]
|
8
|
+
|
9
|
+
begin
|
10
|
+
require 'cane/rake_task'
|
11
|
+
|
12
|
+
desc 'Run cane to check quality metrics'
|
13
|
+
Cane::RakeTask.new(:quality) do |cane|
|
14
|
+
cane.abc_max = 10
|
15
|
+
cane.no_style = true
|
16
|
+
cane.abc_exclude = %w(Foo::Bar#some_method)
|
17
|
+
end
|
18
|
+
|
19
|
+
task default: [:quality]
|
20
|
+
rescue LoadError
|
21
|
+
warn 'cane not available, quality task not provided.'
|
22
|
+
end
|
23
|
+
|
24
|
+
begin
|
25
|
+
require 'churn'
|
26
|
+
task default: [:churn]
|
27
|
+
rescue LoadError
|
28
|
+
warn 'churn not available, churn task not provided.'
|
29
|
+
end
|
data/bin/maze-solver
CHANGED
@@ -23,5 +23,5 @@ if ARGV.length == 5
|
|
23
23
|
main(filename, start_x, start_y, end_x, end_y)
|
24
24
|
else
|
25
25
|
puts "Usage: #{$PROGRAM_NAME} filename start_x start_y end_x end_y\n"
|
26
|
-
puts "Example: #{$PROGRAM_NAME} demo.maze 18 0 38 0\n"
|
26
|
+
puts "Example: #{$PROGRAM_NAME} etc/demo.maze 18 0 38 0\n"
|
27
27
|
end
|
data/lib/maze_solver.rb
CHANGED
@@ -4,6 +4,7 @@ require 'maze_solver/version'
|
|
4
4
|
|
5
5
|
module MazeSolver
|
6
6
|
|
7
|
+
# Maze solver: solves a maze
|
7
8
|
class MazeSolver
|
8
9
|
|
9
10
|
def initialize(args = {})
|
@@ -12,6 +13,12 @@ module MazeSolver
|
|
12
13
|
elsif args[:from_file]
|
13
14
|
@grid = from_file(args[:from_file])
|
14
15
|
end
|
16
|
+
pad_short_rows
|
17
|
+
end
|
18
|
+
|
19
|
+
def pad_short_rows
|
20
|
+
w = self.width
|
21
|
+
@grid.each { |row| row << ' ' * (w - row.length) if w > row.length }
|
15
22
|
end
|
16
23
|
|
17
24
|
def height
|
@@ -42,7 +49,7 @@ module MazeSolver
|
|
42
49
|
def solve(start_x, start_y, end_x, end_y)
|
43
50
|
return false unless visitable?(start_x, start_y)
|
44
51
|
|
45
|
-
visit
|
52
|
+
visit(start_x, start_y)
|
46
53
|
|
47
54
|
return true if [start_x, start_y] == [end_x, end_y]
|
48
55
|
|
@@ -61,7 +68,7 @@ module MazeSolver
|
|
61
68
|
end
|
62
69
|
|
63
70
|
def to_s
|
64
|
-
@grid.join("\n")
|
71
|
+
@grid.join("\n") << "\n"
|
65
72
|
end
|
66
73
|
|
67
74
|
def from_file(filename)
|
@@ -70,5 +77,4 @@ module MazeSolver
|
|
70
77
|
end
|
71
78
|
|
72
79
|
end
|
73
|
-
|
74
80
|
end
|
data/lib/maze_solver/version.rb
CHANGED
@@ -0,0 +1,121 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe MazeSolver do
|
6
|
+
context 'a simple 8 x 3 maze' do
|
7
|
+
before do
|
8
|
+
@maze = MazeSolver::MazeSolver.new(from_grid: <<-GRID
|
9
|
+
********
|
10
|
+
|
11
|
+
********
|
12
|
+
GRID
|
13
|
+
)
|
14
|
+
end
|
15
|
+
|
16
|
+
specify { @maze.width.should eq 8 }
|
17
|
+
specify { @maze.height.should eq 3 }
|
18
|
+
|
19
|
+
it 'should be possible to visit an empty space' do
|
20
|
+
@maze.should be_visitable(0, 1)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should not be possible to visit a wall' do
|
24
|
+
@maze.should_not be_visitable(0, 0)
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should not be possible to visit outside the maze' do
|
28
|
+
@maze.should_not be_visitable(8, 3)
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'should not be possible to visit a visited space' do
|
32
|
+
@maze.visit(0, 1)
|
33
|
+
@maze.should_not be_visitable(0, 1)
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should be possible to visit an unvisited space' do
|
37
|
+
@maze.visit(0, 1)
|
38
|
+
@maze.unvisit(0, 1)
|
39
|
+
@maze.should be_visitable(0, 1)
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'should be soluble' do
|
43
|
+
@maze.solve(0, 1, 7, 1).should be_true
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'should be soluble backwards' do
|
47
|
+
@maze.solve(7, 1, 0, 1).should be_true
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'should be printable' do
|
51
|
+
@maze.to_s.should eq "********\n" +
|
52
|
+
" \n" +
|
53
|
+
"********\n"
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'should be printable when solved' do
|
57
|
+
@maze.solve(0, 1, 7, 1)
|
58
|
+
@maze.to_s.should eq <<-GRID
|
59
|
+
********
|
60
|
+
........
|
61
|
+
********
|
62
|
+
GRID
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
context 'a bigger maze' do
|
68
|
+
it 'should be soluble' do
|
69
|
+
maze = MazeSolver::MazeSolver.new(from_grid: <<-GRID
|
70
|
+
********
|
71
|
+
** *
|
72
|
+
* ** * *
|
73
|
+
* * * *
|
74
|
+
* ** * *
|
75
|
+
* **** *
|
76
|
+
* *
|
77
|
+
********
|
78
|
+
GRID
|
79
|
+
)
|
80
|
+
maze.solve(0, 1, 3, 3).should be_true
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
context 'an impossible maze' do
|
85
|
+
it 'should be insoluble' do
|
86
|
+
maze = MazeSolver::MazeSolver.new(from_grid: <<-GRID
|
87
|
+
********
|
88
|
+
** *
|
89
|
+
* **** *
|
90
|
+
* * * *
|
91
|
+
* ** * *
|
92
|
+
* **** *
|
93
|
+
* *
|
94
|
+
********
|
95
|
+
GRID
|
96
|
+
)
|
97
|
+
maze.solve(0, 1, 3, 3).should be_false
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
context 'from file' do
|
102
|
+
before do
|
103
|
+
test_maze = StringIO.new(<<-DOC
|
104
|
+
****************** *
|
105
|
+
* * **** *
|
106
|
+
* ***** ***** ** *
|
107
|
+
* ***** ******* ** *
|
108
|
+
* * ** ** *
|
109
|
+
* ********** ** *
|
110
|
+
************ *******
|
111
|
+
DOC
|
112
|
+
)
|
113
|
+
File.stub(:open).with('test.maze', 'r').and_return(test_maze)
|
114
|
+
end
|
115
|
+
|
116
|
+
it 'should be creatable' do
|
117
|
+
maze = MazeSolver::MazeSolver.new(from_file: 'test.maze')
|
118
|
+
maze.solve(18, 0, 12, 6).should be_true
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
|
+
require 'coveralls'
|
4
|
+
Coveralls.wear!
|
5
|
+
|
3
6
|
require 'rubygems'
|
4
7
|
require 'bundler/setup'
|
5
8
|
require 'maze_solver'
|
@@ -7,6 +10,5 @@ require 'maze_solver'
|
|
7
10
|
RSpec.configure do |config|
|
8
11
|
config.treat_symbols_as_metadata_keys_with_true_values = true
|
9
12
|
config.run_all_when_everything_filtered = true
|
10
|
-
config.filter_run :focus
|
11
13
|
config.order = 'random'
|
12
14
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: maze-solver
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-07-30 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: A gem to solve a 2D maze.
|
15
15
|
email:
|
@@ -19,8 +19,10 @@ executables:
|
|
19
19
|
extensions: []
|
20
20
|
extra_rdoc_files: []
|
21
21
|
files:
|
22
|
+
- .coveralls.yml
|
22
23
|
- .gitignore
|
23
24
|
- .rspec
|
25
|
+
- .travis.yml
|
24
26
|
- Gemfile
|
25
27
|
- LICENSE.txt
|
26
28
|
- README.md
|
@@ -30,9 +32,8 @@ files:
|
|
30
32
|
- lib/maze_solver.rb
|
31
33
|
- lib/maze_solver/version.rb
|
32
34
|
- maze_solver.gemspec
|
33
|
-
- spec/
|
35
|
+
- spec/maze_solver_spec.rb
|
34
36
|
- spec/spec_helper.rb
|
35
|
-
- spec/test.maze
|
36
37
|
homepage: https://github.com/johnsyweb/ruby_maze_solver#readme
|
37
38
|
licenses: []
|
38
39
|
post_install_message:
|
@@ -58,6 +59,5 @@ signing_key:
|
|
58
59
|
specification_version: 3
|
59
60
|
summary: Written as an exercise
|
60
61
|
test_files:
|
61
|
-
- spec/
|
62
|
+
- spec/maze_solver_spec.rb
|
62
63
|
- spec/spec_helper.rb
|
63
|
-
- spec/test.maze
|
data/spec/maze_spec.rb
DELETED
@@ -1,106 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
|
-
describe MazeSolver do
|
6
|
-
def given_a_simple_8_x_3_maze
|
7
|
-
@maze = MazeSolver::MazeSolver.new(from_grid: "********\n" +
|
8
|
-
" \n" +
|
9
|
-
"********\n"
|
10
|
-
)
|
11
|
-
end
|
12
|
-
|
13
|
-
it 'should have a width of 8' do
|
14
|
-
given_a_simple_8_x_3_maze
|
15
|
-
@maze.width.should eq 8
|
16
|
-
end
|
17
|
-
|
18
|
-
it 'should have a height of 3' do
|
19
|
-
given_a_simple_8_x_3_maze
|
20
|
-
@maze.height.should eq 3
|
21
|
-
end
|
22
|
-
|
23
|
-
it 'should be possible to visit an empty space' do
|
24
|
-
given_a_simple_8_x_3_maze
|
25
|
-
@maze.visitable?(0, 1).should be_true
|
26
|
-
end
|
27
|
-
|
28
|
-
it 'should not be possible to visit a wall' do
|
29
|
-
given_a_simple_8_x_3_maze
|
30
|
-
@maze.visitable?(0, 0).should be_false
|
31
|
-
end
|
32
|
-
|
33
|
-
it 'should not be possible to visit outside the maze' do
|
34
|
-
given_a_simple_8_x_3_maze
|
35
|
-
@maze.visitable?(8, 3).should be_false
|
36
|
-
end
|
37
|
-
|
38
|
-
it 'should not be possible to visit a visited space' do
|
39
|
-
given_a_simple_8_x_3_maze
|
40
|
-
@maze.visit 0, 1
|
41
|
-
@maze.visitable?(0, 1).should be_false
|
42
|
-
end
|
43
|
-
|
44
|
-
it 'should be possible to visit an unvisited space' do
|
45
|
-
given_a_simple_8_x_3_maze
|
46
|
-
@maze.visit 0, 1
|
47
|
-
@maze.unvisit 0, 1
|
48
|
-
@maze.visitable?(0, 1).should be_true
|
49
|
-
end
|
50
|
-
|
51
|
-
it 'should solve a simple maze' do
|
52
|
-
given_a_simple_8_x_3_maze
|
53
|
-
@maze.solve(0, 1, 7, 1).should be_true
|
54
|
-
end
|
55
|
-
|
56
|
-
it 'should solve a simple maze backwards' do
|
57
|
-
given_a_simple_8_x_3_maze
|
58
|
-
@maze.solve(7, 1, 0, 1).should be_true
|
59
|
-
end
|
60
|
-
|
61
|
-
it 'should solve a bigger maze' do
|
62
|
-
maze = MazeSolver::MazeSolver.new(from_grid: "********\n" +
|
63
|
-
" ** *\n" +
|
64
|
-
"* ** * *\n" +
|
65
|
-
"* * * *\n" +
|
66
|
-
"* ** * *\n" +
|
67
|
-
"* **** *\n" +
|
68
|
-
"* *\n" +
|
69
|
-
"********\n")
|
70
|
-
maze.solve(0, 1, 3, 3).should be_true
|
71
|
-
end
|
72
|
-
|
73
|
-
it 'should fail an impossible maze' do
|
74
|
-
maze = MazeSolver::MazeSolver.new(from_grid: "********\n" +
|
75
|
-
" ** *\n" +
|
76
|
-
"* **** *\n" +
|
77
|
-
"* * * *\n" +
|
78
|
-
"* ** * *\n" +
|
79
|
-
"* **** *\n" +
|
80
|
-
"* *\n" +
|
81
|
-
"********\n")
|
82
|
-
maze.solve(0, 1, 3, 3).should be_false
|
83
|
-
end
|
84
|
-
|
85
|
-
it 'should be printable' do
|
86
|
-
given_a_simple_8_x_3_maze
|
87
|
-
@maze.to_s.should eq "********\n" +
|
88
|
-
" \n" +
|
89
|
-
'********'
|
90
|
-
end
|
91
|
-
|
92
|
-
it 'should be printable when solved' do
|
93
|
-
given_a_simple_8_x_3_maze
|
94
|
-
@maze.solve 0, 1, 7, 1
|
95
|
-
@maze.to_s.should eq "********\n" +
|
96
|
-
"........\n" +
|
97
|
-
'********'
|
98
|
-
end
|
99
|
-
|
100
|
-
it 'should be creatable from a file' do
|
101
|
-
maze = MazeSolver::MazeSolver.new(from_file: 'spec/test.maze')
|
102
|
-
maze.solve(18, 0, 12, 6).should be_true
|
103
|
-
end
|
104
|
-
|
105
|
-
end
|
106
|
-
|