maze-solver 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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 [![Build Status](https://travis-ci.org/johnsyweb/ruby_maze_solver.png)](https://travis-ci.org/johnsyweb/ruby_maze_solver) [![Gem Version](https://badge.fury.io/rb/maze-solver.png)](http://badge.fury.io/rb/maze-solver) [![Dependency Status](https://gemnasium.com/johnsyweb/ruby_maze_solver.png)](https://gemnasium.com/johnsyweb/ruby_maze_solver) [![Code Climate](https://codeclimate.com/github/johnsyweb/ruby_maze_solver.png)](https://codeclimate.com/github/johnsyweb/ruby_maze_solver) [![Coverage Status](https://coveralls.io/repos/johnsyweb/ruby_maze_solver/badge.png?branch=master)](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
|
-
|