rmaze 1.0.0 → 1.5.0
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.
- checksums.yaml +4 -4
- data/.gemtest +0 -0
- data/Gemfile +1 -0
- data/Gemfile.lock +5 -0
- data/README.md +63 -3
- data/Rakefile +19 -0
- data/{maze_gen.rb → bin/rmaze} +2 -2
- data/lib/game/game.rb +37 -0
- data/lib/maze/maze.rb +2 -4
- data/lib/maze/maze_cell.rb +6 -1
- data/lib/solver/tree_solver.rb +34 -0
- data/rmaze.gemspec +4 -1
- data/spec/game/game_spec.rb +33 -0
- data/spec/maze/maze_cell_spec.rb +2 -2
- data/spec/maze/maze_spec.rb +2 -2
- data/spec/solver/tree_solver_spec.rb +13 -0
- metadata +42 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 85febacd983d96080346ecd776ce57a069bf3298
|
4
|
+
data.tar.gz: 3fc99125e1fe8afd4c5e01d945b1f0548e9e39e3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 873a51c14c421519625a731e828a571ad8cbf0f375f09ced7d5e7cd31bc34d811788d16d886abad3319b6de1cf6ad21b6dd95232d67ee6efd3fc3eaf27a4609f
|
7
|
+
data.tar.gz: 291daa9e8d1f598c013de04306988d83a3f10e280dec2b92ecfb7c40be682ea45193611b14f2ae486afff75d46d0ae2104e7f87b14b8725b7a71446f09f4c195
|
data/.gemtest
ADDED
File without changes
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -6,6 +6,7 @@ GEM
|
|
6
6
|
docile (1.1.5)
|
7
7
|
json (1.8.1)
|
8
8
|
multi_json (1.10.1)
|
9
|
+
rake (10.1.0)
|
9
10
|
rspec (3.1.0)
|
10
11
|
rspec-core (~> 3.1.0)
|
11
12
|
rspec-expectations (~> 3.1.0)
|
@@ -33,6 +34,10 @@ PLATFORMS
|
|
33
34
|
|
34
35
|
DEPENDENCIES
|
35
36
|
OptionParser (~> 0.5.1)
|
37
|
+
rake (~> 10.1.0)
|
36
38
|
rspec (~> 3.1.0)
|
37
39
|
rubytree (~> 0.9.4)
|
38
40
|
simplecov
|
41
|
+
|
42
|
+
BUNDLED WITH
|
43
|
+
1.11.2
|
data/README.md
CHANGED
@@ -1,4 +1,64 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# RMaze
|
2
|
+
Ruby library and tool for 2D maze generation
|
3
3
|
|
4
|
-
|
4
|
+
[](http://travis-ci.org/pedrohml/rmaze)
|
5
|
+
[](https://hakiri.io/github/pedrohml/rmaze/master)
|
6
|
+
|
7
|
+
#### Description
|
8
|
+
This simple library/tool generates 2D mazes with customizable dimensions.
|
9
|
+
|
10
|
+
#### Tool usage
|
11
|
+
The **rmaze** is in initial version and its simple to use
|
12
|
+
|
13
|
+
```
|
14
|
+
Usage: rmaze.rb [options]
|
15
|
+
|
16
|
+
Basic options:
|
17
|
+
-w, --width width Specify the maze width (default: 10)
|
18
|
+
-h, --height height Specify the maze height (default: 10)
|
19
|
+
|
20
|
+
Algorithms:
|
21
|
+
-b, --backtrace Choose backtrace algorithm (default)
|
22
|
+
```
|
23
|
+
|
24
|
+
#### Tool usage examples
|
25
|
+
|
26
|
+
Default usage (*width=10, height=10*)
|
27
|
+
```
|
28
|
+
> rmaze
|
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
|
+
Generate mazes with customized dimensions (*width=5, height=2*)
|
54
|
+
```
|
55
|
+
> rmaze -w 5 -h 2
|
56
|
+
|
57
|
+
# # # # # # # # # # #
|
58
|
+
# #
|
59
|
+
# # # # # # # # #
|
60
|
+
# # #
|
61
|
+
# # # # # # # # # # #
|
62
|
+
```
|
63
|
+
|
64
|
+
Enjoy !
|
data/Rakefile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require "bundler/gem_tasks"
|
3
|
+
require 'rspec/core/rake_task'
|
4
|
+
|
5
|
+
|
6
|
+
begin
|
7
|
+
RSpec::Core::RakeTask.new(:spec)
|
8
|
+
|
9
|
+
desc 'Rake test'
|
10
|
+
task default: :test
|
11
|
+
rescue LoadError
|
12
|
+
fail
|
13
|
+
end
|
14
|
+
|
15
|
+
desc 'Pre-commit hook (test)'
|
16
|
+
task pre_commit: :test
|
17
|
+
|
18
|
+
desc 'Run spec tests'
|
19
|
+
task test: :spec
|
data/{maze_gen.rb → bin/rmaze}
RENAMED
@@ -9,7 +9,7 @@ options = {
|
|
9
9
|
:algorithm => :backtrace
|
10
10
|
}
|
11
11
|
OptionParser.new do |opts|
|
12
|
-
opts.banner = "Usage:
|
12
|
+
opts.banner = "Usage: rmaze [options]"
|
13
13
|
|
14
14
|
opts.separator ""
|
15
15
|
opts.separator "Basic options:"
|
@@ -37,4 +37,4 @@ else
|
|
37
37
|
end
|
38
38
|
|
39
39
|
maze.generate
|
40
|
-
maze.
|
40
|
+
maze.print
|
data/lib/game/game.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'solver/tree_solver'
|
2
|
+
|
3
|
+
class Game
|
4
|
+
def initialize(maze)
|
5
|
+
@maze = maze
|
6
|
+
end
|
7
|
+
|
8
|
+
def select_goal_cell(dificulty)
|
9
|
+
dificulty = dificulty.to_sym
|
10
|
+
solver = TreeSolver.new(@maze)
|
11
|
+
start_x, start_y = 0, 0
|
12
|
+
paths = solver.paths(start_x, start_y)
|
13
|
+
leafs = {}
|
14
|
+
paths.each_leaf do |leaf|
|
15
|
+
leafs[leaf.node_depth] = leaf
|
16
|
+
end
|
17
|
+
depths = leafs.keys.sort
|
18
|
+
case dificulty
|
19
|
+
when :easy
|
20
|
+
selected_depth = depths[(depths.size*0.25).ceil]
|
21
|
+
when :medium
|
22
|
+
selected_depth = depths[(depths.size*0.5).ceil]
|
23
|
+
when :hard
|
24
|
+
selected_depth = depths.last
|
25
|
+
else
|
26
|
+
selected_depth = depths[rand((depths.size/2.0).ceil) + (depths.size/2.0).ceil]
|
27
|
+
end
|
28
|
+
leafs[selected_depth].content
|
29
|
+
end
|
30
|
+
|
31
|
+
def generate_goal(dificulty)
|
32
|
+
selected_cell = select_goal_cell(dificulty)
|
33
|
+
i, j = @maze.xy_to_ij(selected_cell.x, selected_cell.y)
|
34
|
+
@maze.matrix[i][j] = 2
|
35
|
+
@maze
|
36
|
+
end
|
37
|
+
end
|
data/lib/maze/maze.rb
CHANGED
@@ -2,8 +2,6 @@ require 'maze/maze_cell'
|
|
2
2
|
|
3
3
|
class Maze
|
4
4
|
protected
|
5
|
-
attr_reader :matrix
|
6
|
-
|
7
5
|
def initialize_matrix
|
8
6
|
@matrix = []
|
9
7
|
(0...@height_full).each do
|
@@ -30,7 +28,7 @@ class Maze
|
|
30
28
|
end
|
31
29
|
|
32
30
|
public
|
33
|
-
attr_reader :mirrored, :width, :height, :width_full, :height_full
|
31
|
+
attr_reader :mirrored, :width, :height, :width_full, :height_full, :matrix
|
34
32
|
|
35
33
|
def initialize(width, height)
|
36
34
|
@mirrored = false
|
@@ -40,7 +38,7 @@ class Maze
|
|
40
38
|
@hash = "#{@width}#{@height}".to_i # optimized pre-computed hash
|
41
39
|
end
|
42
40
|
|
43
|
-
def
|
41
|
+
def print
|
44
42
|
@matrix.each do |row|
|
45
43
|
puts row.join(' ').gsub(/0/, ' ').gsub(/1/, '#').gsub(/2/, 'X')
|
46
44
|
end
|
data/lib/maze/maze_cell.rb
CHANGED
@@ -8,7 +8,7 @@ class MazeCell
|
|
8
8
|
@hash = "#{@maze.hash}#{@x}#{@y}".to_i
|
9
9
|
end
|
10
10
|
|
11
|
-
def
|
11
|
+
def print
|
12
12
|
i, j = @maze.xy_to_ij(@x, @y)
|
13
13
|
puts " #{@maze.value(i - 1, j)} "
|
14
14
|
puts "#{@maze.value(i, j - 1)} #{@maze.value(i, j)} #{@maze.value(i, j + 1)}"
|
@@ -67,6 +67,11 @@ class MazeCell
|
|
67
67
|
neighbours << down unless has_wall_down?
|
68
68
|
neighbours
|
69
69
|
end
|
70
|
+
|
71
|
+
def value
|
72
|
+
i, j = xy_to_ij(@x, @y)
|
73
|
+
@maze.value(i, j)
|
74
|
+
end
|
70
75
|
|
71
76
|
def hash
|
72
77
|
@hash
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'tree'
|
2
|
+
|
3
|
+
class TreeSolver
|
4
|
+
attr_reader :maze
|
5
|
+
|
6
|
+
def initialize(maze)
|
7
|
+
@maze = maze
|
8
|
+
end
|
9
|
+
|
10
|
+
def paths(start_x, start_y)
|
11
|
+
current_cell = @maze.cell(start_x, start_y)
|
12
|
+
root_node = current_node = Tree::TreeNode.new("#{current_cell.x},#{current_cell.y}", current_cell)
|
13
|
+
visited_cells = [current_cell]
|
14
|
+
stack_node = []
|
15
|
+
stack_cell = []
|
16
|
+
while visited_cells.size != @maze.width * @maze.height
|
17
|
+
neighbours = current_cell.connected_neighbours
|
18
|
+
unvisited_neighbours = neighbours - visited_cells
|
19
|
+
if unvisited_neighbours.size == 0
|
20
|
+
current_cell = stack_cell.pop
|
21
|
+
current_node = stack_node.pop
|
22
|
+
elsif unvisited_neighbours.size >= 1
|
23
|
+
current_cell = unvisited_neighbours.shift
|
24
|
+
stack_cell += unvisited_neighbours
|
25
|
+
stack_node += [current_node]*unvisited_neighbours.size
|
26
|
+
end
|
27
|
+
visited_cells << current_cell
|
28
|
+
new_node = Tree::TreeNode.new("#{current_cell.x},#{current_cell.y}", current_cell)
|
29
|
+
current_node << new_node
|
30
|
+
current_node = new_node
|
31
|
+
end
|
32
|
+
root_node
|
33
|
+
end
|
34
|
+
end
|
data/rmaze.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'rmaze'
|
3
|
-
s.version = '1.
|
3
|
+
s.version = '1.5.0'
|
4
4
|
s.date = '2014-10-01'
|
5
5
|
s.licenses = ["MIT"]
|
6
6
|
s.platform = Gem::Platform::RUBY
|
@@ -10,6 +10,9 @@ Gem::Specification.new do |s|
|
|
10
10
|
s.email = 'pedrohml@gmail.com'
|
11
11
|
s.files = `git ls-files`.split("\n")
|
12
12
|
s.test_files = `git ls-files -- spec/*`.split("\n")
|
13
|
+
s.executables << 'rmaze'
|
13
14
|
s.homepage = 'https://github.com/pedrohml/rmaze'
|
14
15
|
s.require_paths = ["lib"]
|
16
|
+
s.add_runtime_dependency 'rubytree', '~> 0.9'
|
17
|
+
s.add_runtime_dependency 'OptionParser', '~> 0.5.1'
|
15
18
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
describe Game do
|
2
|
+
before do
|
3
|
+
@maze = MazeBTrace.new(8, 8)
|
4
|
+
@maze.generate
|
5
|
+
@game = Game.new(@maze)
|
6
|
+
end
|
7
|
+
|
8
|
+
it '#select_goal_cell' do
|
9
|
+
selected_cell = @game.select_goal_cell(:hard)
|
10
|
+
expect([selected_cell.x, selected_cell.y]).not_to eq([0, 0])
|
11
|
+
expect(selected_cell.connected_neighbours.size).to eq(1)
|
12
|
+
end
|
13
|
+
|
14
|
+
it '#generate_goal :easy' do
|
15
|
+
maze = @game.generate_goal(:easy)
|
16
|
+
expect(maze.matrix.flatten).to include(2)
|
17
|
+
end
|
18
|
+
|
19
|
+
it '#generate_goal :easy' do
|
20
|
+
maze = @game.generate_goal(:medium)
|
21
|
+
expect(maze.matrix.flatten).to include(2)
|
22
|
+
end
|
23
|
+
|
24
|
+
it '#generate_goal :easy' do
|
25
|
+
maze = @game.generate_goal(:hard)
|
26
|
+
expect(maze.matrix.flatten).to include(2)
|
27
|
+
end
|
28
|
+
|
29
|
+
it '#generate_goal :easy' do
|
30
|
+
maze = @game.generate_goal(:random)
|
31
|
+
expect(maze.matrix.flatten).to include(2)
|
32
|
+
end
|
33
|
+
end
|
data/spec/maze/maze_cell_spec.rb
CHANGED
@@ -82,10 +82,10 @@ describe MazeCell do
|
|
82
82
|
expect(maze_cell != nil).to be_truthy
|
83
83
|
end
|
84
84
|
|
85
|
-
it '#
|
85
|
+
it '#print' do
|
86
86
|
allow($stdout).to receive(:puts).exactly(3).times
|
87
87
|
maze_cell = @maze.cell(0, 0)
|
88
|
-
maze_cell.
|
88
|
+
maze_cell.print
|
89
89
|
end
|
90
90
|
|
91
91
|
it '#inspect' do
|
data/spec/maze/maze_spec.rb
CHANGED
@@ -0,0 +1,13 @@
|
|
1
|
+
describe TreeSolver do
|
2
|
+
before do
|
3
|
+
@maze = MazeBTrace.new(4, 4)
|
4
|
+
@maze.generate
|
5
|
+
@tree_solver = TreeSolver.new(@maze)
|
6
|
+
end
|
7
|
+
|
8
|
+
it '#paths' do
|
9
|
+
paths = @tree_solver.paths(0, 0)
|
10
|
+
expect(paths.name).to eq('0,0')
|
11
|
+
expect(paths.size).to eq(16)
|
12
|
+
end
|
13
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rmaze
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pedro Lira
|
@@ -9,13 +9,43 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
date: 2014-10-01 00:00:00.000000000 Z
|
12
|
-
dependencies:
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rubytree
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.9'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.9'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: OptionParser
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.5.1
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.5.1
|
13
41
|
description: Ruby library for maze generation
|
14
42
|
email: pedrohml@gmail.com
|
15
|
-
executables:
|
43
|
+
executables:
|
44
|
+
- rmaze
|
16
45
|
extensions: []
|
17
46
|
extra_rdoc_files: []
|
18
47
|
files:
|
48
|
+
- ".gemtest"
|
19
49
|
- ".gitignore"
|
20
50
|
- ".rspec"
|
21
51
|
- ".ruby-gemset"
|
@@ -23,15 +53,20 @@ files:
|
|
23
53
|
- Gemfile
|
24
54
|
- Gemfile.lock
|
25
55
|
- README.md
|
56
|
+
- Rakefile
|
57
|
+
- bin/rmaze
|
58
|
+
- lib/game/game.rb
|
26
59
|
- lib/maze/maze.rb
|
27
60
|
- lib/maze/maze_btrace.rb
|
28
61
|
- lib/maze/maze_cell.rb
|
29
62
|
- lib/rmaze.rb
|
30
|
-
-
|
63
|
+
- lib/solver/tree_solver.rb
|
31
64
|
- rmaze.gemspec
|
65
|
+
- spec/game/game_spec.rb
|
32
66
|
- spec/maze/maze_btrace_spec.rb
|
33
67
|
- spec/maze/maze_cell_spec.rb
|
34
68
|
- spec/maze/maze_spec.rb
|
69
|
+
- spec/solver/tree_solver_spec.rb
|
35
70
|
- spec/spec_helper.rb
|
36
71
|
homepage: https://github.com/pedrohml/rmaze
|
37
72
|
licenses:
|
@@ -53,12 +88,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
53
88
|
version: '0'
|
54
89
|
requirements: []
|
55
90
|
rubyforge_project:
|
56
|
-
rubygems_version: 2.
|
91
|
+
rubygems_version: 2.4.8
|
57
92
|
signing_key:
|
58
93
|
specification_version: 4
|
59
94
|
summary: RMaze
|
60
95
|
test_files:
|
96
|
+
- spec/game/game_spec.rb
|
61
97
|
- spec/maze/maze_btrace_spec.rb
|
62
98
|
- spec/maze/maze_cell_spec.rb
|
63
99
|
- spec/maze/maze_spec.rb
|
100
|
+
- spec/solver/tree_solver_spec.rb
|
64
101
|
- spec/spec_helper.rb
|