rmaze 1.5.0 → 2.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 85febacd983d96080346ecd776ce57a069bf3298
4
- data.tar.gz: 3fc99125e1fe8afd4c5e01d945b1f0548e9e39e3
3
+ metadata.gz: e9e0430fb1d38141827770a72ae3438a451ed1ca
4
+ data.tar.gz: 15a61f5a73f128132ed27b0a2f08b2bfaa5bb3e4
5
5
  SHA512:
6
- metadata.gz: 873a51c14c421519625a731e828a571ad8cbf0f375f09ced7d5e7cd31bc34d811788d16d886abad3319b6de1cf6ad21b6dd95232d67ee6efd3fc3eaf27a4609f
7
- data.tar.gz: 291daa9e8d1f598c013de04306988d83a3f10e280dec2b92ecfb7c40be682ea45193611b14f2ae486afff75d46d0ae2104e7f87b14b8725b7a71446f09f4c195
6
+ metadata.gz: a5a3263729d2f09ded3176dbef2531779c8ebb1f7f3ab38342b473dabd4a94142c1ab7709276c264788eca2f201da5a39728bd4720186fd5da88c096521bfc8a
7
+ data.tar.gz: 324f2f23e46d31728e3e4e77f71f31fd958aea40b4bf056b348a33b42c9f9213f490c3e0b3fe25bc68bd0d3ad19aacc8a79820fa26cb105162180f4ea106b03d
@@ -1 +1 @@
1
- ruby-2.1.3
1
+ ruby-2.2.1
data/Gemfile CHANGED
@@ -6,5 +6,5 @@ gem 'rake', '~> 10.1.0'
6
6
 
7
7
  group :test do
8
8
  gem 'rspec', '~> 3.1.0'
9
- gem 'simplecov', :require => false
9
+ gem 'coveralls', require: false
10
10
  end
@@ -2,11 +2,27 @@ GEM
2
2
  remote: https://rubygems.org/
3
3
  specs:
4
4
  OptionParser (0.5.1)
5
+ coveralls (0.8.10)
6
+ json (~> 1.8)
7
+ rest-client (>= 1.6.8, < 2)
8
+ simplecov (~> 0.11.0)
9
+ term-ansicolor (~> 1.3)
10
+ thor (~> 0.19.1)
11
+ tins (~> 1.6.0)
5
12
  diff-lcs (1.2.5)
6
13
  docile (1.1.5)
14
+ domain_name (0.5.25)
15
+ unf (>= 0.0.5, < 1.0.0)
16
+ http-cookie (1.0.2)
17
+ domain_name (~> 0.5)
7
18
  json (1.8.1)
8
- multi_json (1.10.1)
19
+ mime-types (2.99)
20
+ netrc (0.11.0)
9
21
  rake (10.1.0)
22
+ rest-client (1.8.0)
23
+ http-cookie (>= 1.0.2, < 2.0)
24
+ mime-types (>= 1.16, < 3.0)
25
+ netrc (~> 0.7)
10
26
  rspec (3.1.0)
11
27
  rspec-core (~> 3.1.0)
12
28
  rspec-expectations (~> 3.1.0)
@@ -22,22 +38,29 @@ GEM
22
38
  rubytree (0.9.4)
23
39
  json (~> 1.8)
24
40
  structured_warnings (~> 0.1)
25
- simplecov (0.9.1)
41
+ simplecov (0.11.1)
26
42
  docile (~> 1.1.0)
27
- multi_json (~> 1.0)
28
- simplecov-html (~> 0.8.0)
29
- simplecov-html (0.8.0)
43
+ json (~> 1.8)
44
+ simplecov-html (~> 0.10.0)
45
+ simplecov-html (0.10.0)
30
46
  structured_warnings (0.1.4)
47
+ term-ansicolor (1.3.2)
48
+ tins (~> 1.0)
49
+ thor (0.19.1)
50
+ tins (1.6.0)
51
+ unf (0.1.4)
52
+ unf_ext
53
+ unf_ext (0.0.7.1)
31
54
 
32
55
  PLATFORMS
33
56
  ruby
34
57
 
35
58
  DEPENDENCIES
36
59
  OptionParser (~> 0.5.1)
60
+ coveralls
37
61
  rake (~> 10.1.0)
38
62
  rspec (~> 3.1.0)
39
63
  rubytree (~> 0.9.4)
40
- simplecov
41
64
 
42
65
  BUNDLED WITH
43
66
  1.11.2
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Pedro Henrique Marques Lira
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md CHANGED
@@ -1,17 +1,23 @@
1
1
  # RMaze
2
- Ruby library and tool for 2D maze generation
2
+ Ruby library for multidimensional maze generation
3
3
 
4
- [![Build Status](http://travis-ci.org/pedrohml/rmaze.svg?branch=master)](http://travis-ci.org/pedrohml/rmaze)
4
+ [![Gem Version](https://img.shields.io/gem/v/rmaze.svg)](https://rubygems.org/gems/rmaze)
5
+ [![Build Status](https://img.shields.io/travis/pedrohml/rmaze/master.svg)](http://travis-ci.org/pedrohml/rmaze)
6
+ [![Coverage Status](https://img.shields.io/coveralls/pedrohml/rmaze.svg)](https://coveralls.io/github/pedrohml/rmaze)
5
7
  [![Security](http://hakiri.io/github/pedrohml/rmaze/master.svg)](https://hakiri.io/github/pedrohml/rmaze/master)
8
+ [![License](https://img.shields.io/github/license/pedrohml/rmaze.svg)](https://github.com/pedrohml/rmaze/blob/master/LICENSE.txt)
6
9
 
7
10
  #### Description
8
- This simple library/tool generates 2D mazes with customizable dimensions.
11
+ This library generates multidimensional mazes.
12
+
13
+ - What the purpose ? Mainly, games.
14
+ - What do I want Nth-d mazes for ? I do not know yet.
9
15
 
10
16
  #### Tool usage
11
- The **rmaze** is in initial version and its simple to use
17
+ The tool **rmaze** is in initial version and only supports bidimensional mazes.
12
18
 
13
19
  ```
14
- Usage: rmaze.rb [options]
20
+ Usage: rmaze [options]
15
21
 
16
22
  Basic options:
17
23
  -w, --width width Specify the maze width (default: 10)
data/bin/rmaze CHANGED
@@ -27,14 +27,18 @@ OptionParser.new do |opts|
27
27
  end
28
28
  end.parse!
29
29
 
30
- maze = nil
30
+ maze = Maze.new options[:width], options[:height]
31
+ maze.set_raw_value_all 1
32
+
31
33
  case options[:algorithm]
32
34
  when :backtrace
33
- maze = MazeBTrace.new(options[:width], options[:height])
35
+ backtrace = Backtrace.new maze
36
+ backtrace.generate
34
37
  else
35
38
  $stderr.puts "Error: the algorithm must be set."
36
39
  exit(-1)
37
40
  end
38
41
 
39
- maze.generate
40
- maze.print
42
+ maze.matrix.each_with_index do |row, index|
43
+ puts row.map(&:to_s).join(' ').gsub('0', ' ').gsub('1', '#')
44
+ end
@@ -0,0 +1,46 @@
1
+ require 'maze/maze'
2
+
3
+ class Backtrace
4
+ attr_reader :maze
5
+
6
+ def initialize(maze)
7
+ @maze = maze
8
+ end
9
+
10
+ def generate
11
+ stack = []
12
+ visited_cells = []
13
+ all_cells = []
14
+ @maze.set_raw_value_all 1
15
+ all_cells = @maze.cells
16
+
17
+ all_cells.each do |cell|
18
+ @maze.set_value *cell.coords.clone.push(0)
19
+ end
20
+
21
+ current_cell = @maze.cell *@maze.dimensions.map { |d| rand(d) }
22
+ visited_cells.push current_cell
23
+
24
+ while visited_cells.size != @maze.total_cells
25
+ neighbours = current_cell.neighbours
26
+ visited_cells.push current_cell
27
+ unvisited_neighbours = (neighbours - visited_cells)
28
+ if !unvisited_neighbours.empty?
29
+ stack.push current_cell
30
+ random_neighbour = unvisited_neighbours.shuffle.shift
31
+ @maze.connect_cells current_cell, random_neighbour
32
+ current_cell = random_neighbour
33
+ visited_cells.push current_cell
34
+ elsif !stack.empty?
35
+ current_cell = stack.pop
36
+ else
37
+ unvisited_index_cells = all_cells - visited_cells
38
+ unvisited_index_cell = unvisited_index_cells.shuffle.shift
39
+ current_cell = unvisited_index_cell
40
+ visited_cells.push current_cell
41
+ end
42
+ visited_cells.uniq!
43
+ end
44
+ @maze
45
+ end
46
+ end
@@ -7,9 +7,9 @@ class Game
7
7
 
8
8
  def select_goal_cell(dificulty)
9
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)
10
+ solver = TreeSolver.new @maze
11
+ start_coords = [0]*@maze.dimensions.length
12
+ paths = solver.paths *start_coords
13
13
  leafs = {}
14
14
  paths.each_leaf do |leaf|
15
15
  leafs[leaf.node_depth] = leaf
@@ -17,21 +17,23 @@ class Game
17
17
  depths = leafs.keys.sort
18
18
  case dificulty
19
19
  when :easy
20
- selected_depth = depths[(depths.size*0.25).ceil]
20
+ selected_depth = depths[(depths.size/4).ceil]
21
21
  when :medium
22
- selected_depth = depths[(depths.size*0.5).ceil]
22
+ selected_depth = depths[(depths.size/2).ceil]
23
23
  when :hard
24
24
  selected_depth = depths.last
25
25
  else
26
- selected_depth = depths[rand((depths.size/2.0).ceil) + (depths.size/2.0).ceil]
26
+ selected_depth = depths[(depths.size/2.0).floor + rand((depths.size/2.0).round)]
27
27
  end
28
28
  leafs[selected_depth].content
29
29
  end
30
30
 
31
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
32
+ selected_cell = select_goal_cell dificulty
33
+ indices = @maze.coords_to_indices *selected_cell.coords
34
+ params = indices.clone
35
+ params.push 2
36
+ @maze.set_raw_value *params
35
37
  @maze
36
38
  end
37
39
  end
@@ -2,73 +2,140 @@ require 'maze/maze_cell'
2
2
 
3
3
  class Maze
4
4
  protected
5
- def initialize_matrix
6
- @matrix = []
7
- (0...@height_full).each do
8
- @matrix << [0]*@width_full
5
+ def allocate(value = 0)
6
+ axis = []
7
+ axis_before = []
8
+ @raw_dimensions.reverse.each_with_index do |dr, dr_index|
9
+ axis = []
10
+ if dr_index == 0
11
+ axis = [value] * dr
12
+ else
13
+ (0...dr).each do
14
+ axis << axis_before.clone
15
+ end
16
+ end
17
+ axis_before = axis
9
18
  end
19
+ @matrix = axis
10
20
  end
11
21
 
12
- def make_value(value = 0)
13
- (0...@height_full).each do |i|
14
- (0...@width_full).each do |j|
15
- @matrix[i][j] = value
16
- end
17
- end
22
+ def set_between_cells(cell_a, cell_b, value)
23
+ indices = between_cells cell_a, cell_b
24
+ params = indices.clone
25
+ params.push value
26
+ set_raw_value *params
27
+ indices
28
+ end
29
+
30
+ def evaluate_indices(dim_sizes)
31
+ matrix_aux = @matrix
32
+ indices = []
33
+ stack = []
34
+ begin
35
+ if not stack.empty? and stack.last >= dim_sizes[stack.length - 1]
36
+ stack.pop
37
+ stack[-1] += 1 if not stack.empty?
38
+ elsif stack.length < dim_sizes.length - 1
39
+ matrix_before = matrix_aux
40
+ stack.push 0
41
+ matrix_aux = matrix_aux[stack.last]
42
+ else
43
+ (0...dim_sizes.last).each { |d| indices.push(stack + [d]) }
44
+ stack[-1] += 1
45
+ end
46
+ end until stack.empty?
47
+ indices
48
+ end
49
+
50
+ public
51
+ attr_reader :dimensions, :width_full, :height_full, :matrix
52
+
53
+ def initialize(*dimensions)
54
+ @dimensions = dimensions.map { |d| d.to_i }.freeze
55
+ @raw_dimensions = @dimensions.map { |d| 1 + 2*d }.freeze
56
+ allocate 0
57
+ @hash = @dimensions.reduce(""){ |accum, d| "#{accum}#{d}" }.to_i
18
58
  end
19
59
 
20
- def make_unconnected
21
- make_value(1)
22
- (0...@width).each do |x|
23
- (0...@height).each do |y|
24
- i, j = xy_to_ij(x, y)
25
- @matrix[i][j] = 0
26
- end
27
- end
60
+ def total_cells
61
+ dimensions.reduce(1) { |accum, d| accum*d }
62
+ end
63
+
64
+ def total_raw
65
+ dimensions.reduce(1) { |accum, d| accum*(1 + 2*d) }
66
+ end
67
+
68
+ def coords_to_indices(*coords)
69
+ coords.map { |c| 1 + 2 * c }
28
70
  end
29
71
 
30
- public
31
- attr_reader :mirrored, :width, :height, :width_full, :height_full, :matrix
32
-
33
- def initialize(width, height)
34
- @mirrored = false
35
- @height, @width = height.to_i, width.to_i
36
- @height_full, @width_full = (1 + 2*@height), (1 + 2*@width)
37
- initialize_matrix
38
- @hash = "#{@width}#{@height}".to_i # optimized pre-computed hash
72
+ def get_raw_value(*indices)
73
+ matrix_aux = @matrix
74
+ indices.each_with_index do |c|
75
+ matrix_aux = matrix_aux[c]
76
+ end
77
+ matrix_aux
39
78
  end
40
79
 
41
- def print
42
- @matrix.each do |row|
43
- puts row.join(' ').gsub(/0/, ' ').gsub(/1/, '#').gsub(/2/, 'X')
80
+ def set_raw_value(*indices)
81
+ matrix_aux = @matrix
82
+ indices = indices.clone
83
+ value = indices.pop
84
+ indices.each_with_index do |c, c_index|
85
+ matrix_aux[c] = value if c_index == indices.length - 1
86
+ matrix_aux = matrix_aux[c]
44
87
  end
45
- self
88
+ matrix_aux
46
89
  end
47
90
 
48
- def value(i, j)
49
- @matrix[i][j]
91
+ def set_raw_value_all(value)
92
+ allocate value
50
93
  end
51
94
 
52
- def cell(x, y)
53
- MazeCell.new(self, x, y)
95
+ def get_value(*coords)
96
+ get_raw_value *self.coords_to_indices(*coords)
54
97
  end
55
98
 
56
- def xy_to_ij(x, y)
57
- x, y = x % @width, y % @height if @mirrored
58
- i = 1 + (2 * y)
59
- j = 1 + (2 * x)
60
- [i, j]
99
+ def set_value(*coords)
100
+ coords = coords.clone
101
+ value = coords.pop
102
+ set_raw_value *self.coords_to_indices(*coords).push(value)
61
103
  end
62
104
 
63
- def generate
64
- self
105
+ def cell(*coords)
106
+ params = coords.clone
107
+ params.unshift self
108
+ MazeCell.new *params
65
109
  end
66
110
 
111
+ def cells
112
+ evaluate_indices(@dimensions).map { |coord| cell *coord }
113
+ end
114
+
115
+ def between_cells(cell_a, cell_b)
116
+ indices_a = coords_to_indices *cell_a.coords
117
+ indices_b = coords_to_indices *cell_b.coords
118
+ indices_a.zip(indices_b).map { |pair| (pair[0] + pair[1]) / 2.0 }
119
+ end
120
+
121
+ def connect_cells(cell_a, cell_b)
122
+ set_between_cells cell_a, cell_b, 0
123
+ end
124
+
125
+ def disconnect_cells(cell_a, cell_b)
126
+ set_between_cells cell_a, cell_b, 1
127
+ end
128
+
67
129
  def hash
68
130
  @hash
69
131
  end
70
132
 
71
133
  def inspect
72
- "#<#{self.class}: @width=#{@width}, @height=#{@height}>"
134
+ if not @inspect
135
+ d_index = 0
136
+ dimension_list = @dimensions.map { |d| "@d#{d_index+=1}=#{d}" }
137
+ @inspect = "#<#{self.class}: #{dimension_list.join(', ')}>"
138
+ end
139
+ @inspect
73
140
  end
74
141
  end
@@ -1,99 +1,101 @@
1
1
  class MazeCell
2
- attr_reader :maze, :x, :y
2
+ attr_reader :maze, :coords
3
3
 
4
- def initialize(maze, x, y)
5
- @maze = maze
6
- @x, @y = x.to_i, y.to_i
7
- @x, @y = x % @maze.width, y % @maze.height if @maze.mirrored
8
- @hash = "#{@maze.hash}#{@x}#{@y}".to_i
4
+ def initialize(*params)
5
+ params = params.clone
6
+ @maze = params.shift
7
+ @coords = params.map { |c| c.to_i }
8
+ @hash = "#{@maze.hash}#{ @coords.reduce(""){ |accum, c| "#{accum}#{c}" }.to_i }".to_i
9
9
  end
10
10
 
11
- def print
12
- i, j = @maze.xy_to_ij(@x, @y)
13
- puts " #{@maze.value(i - 1, j)} "
14
- puts "#{@maze.value(i, j - 1)} #{@maze.value(i, j)} #{@maze.value(i, j + 1)}"
15
- puts " #{@maze.value(i + 1, j)} "
16
- end
17
-
18
- def left
19
- MazeCell.new(@maze, @x - 1, @y) if @maze.mirrored || @x > 0
20
- end
21
-
22
- def up
23
- MazeCell.new(@maze, @x, @y - 1) if @maze.mirrored || @y > 0
24
- end
25
-
26
- def right
27
- MazeCell.new(@maze, @x + 1, @y) if @maze.mirrored || @x < (@maze.width - 1)
28
- end
29
-
30
- def down
31
- MazeCell.new(@maze, @x, @y + 1) if @maze.mirrored || @y < (@maze.height - 1)
11
+ def value
12
+ @maze.get_value *@coords
32
13
  end
33
14
 
34
- def has_wall_left?
35
- i, j = @maze.xy_to_ij(@x, @y)
36
- @maze.value(i, j - 1) != 0
15
+ def backward(dimension_index)
16
+ coords = @coords.clone
17
+ coords[dimension_index] -= 1
18
+ params = coords.clone
19
+ params.unshift @maze
20
+ MazeCell.new *params if @coords[dimension_index] > 0
37
21
  end
38
22
 
39
- def has_wall_up?
40
- i, j = @maze.xy_to_ij(@x, @y)
41
- @maze.value(i - 1, j) != 0
23
+ def forward(dimension_index)
24
+ coords = @coords.clone
25
+ coords[dimension_index] += 1
26
+ params = coords.clone
27
+ params.unshift @maze
28
+ MazeCell.new *params if @coords[dimension_index] < (@maze.dimensions[dimension_index] - 1)
42
29
  end
43
30
 
44
- def has_wall_right?
45
- i, j = @maze.xy_to_ij(@x, @y)
46
- @maze.value(i, j + 1) != 0
31
+ def has_wall_forward(dimension_index)
32
+ indices = @maze.coords_to_indices *@coords
33
+ indices[dimension_index] += 1
34
+ @coords[dimension_index] >= @maze.dimensions[dimension_index] - 1 or @maze.get_raw_value(*indices) == 1
47
35
  end
48
36
 
49
- def has_wall_down?
50
- i, j = @maze.xy_to_ij(@x, @y)
51
- @maze.value(i + 1, j) != 0
37
+ def has_wall_backward(dimension_index)
38
+ indices = @maze.coords_to_indices *@coords
39
+ indices[dimension_index] -= 1
40
+ @coords[dimension_index] <= 0 or @maze.get_raw_value(*indices) == 1
52
41
  end
53
42
 
54
43
  def connected?
55
- !(has_wall_left? && has_wall_up? && has_wall_right? && has_wall_down?)
44
+ has_wall = true
45
+ (0...@maze.dimensions.length).each do |d|
46
+ has_wall = has_wall && has_wall_forward(d) && has_wall_backward(d)
47
+ break unless has_wall
48
+ end
49
+ not has_wall
56
50
  end
57
51
 
58
52
  def neighbours
59
- [left, up, right, down].compact
53
+ (0...@maze.dimensions.length).map { |d| [forward(d), backward(d)] }.flatten.compact
60
54
  end
61
55
 
62
56
  def connected_neighbours
63
57
  neighbours = []
64
- neighbours << left unless has_wall_left?
65
- neighbours << up unless has_wall_up?
66
- neighbours << right unless has_wall_right?
67
- neighbours << down unless has_wall_down?
58
+ (0...@maze.dimensions.length).each do |d|
59
+ neighbours << forward(d) unless has_wall_forward(d)
60
+ neighbours << backward(d) unless has_wall_backward(d)
61
+ end
68
62
  neighbours
69
63
  end
70
64
 
71
- def value
72
- i, j = xy_to_ij(@x, @y)
73
- @maze.value(i, j)
74
- end
75
-
76
65
  def hash
77
66
  @hash
78
67
  end
79
68
 
80
69
  def eql?(object)
81
70
  if (object.class == self.class)
82
- @x == object.x && @y == object.y && @maze == object.maze
71
+ eq = (@maze == object.maze)
72
+ @coords.each_with_index do |c, c_idx|
73
+ eq = eq && c == object[c_idx]
74
+ end
75
+ eq
83
76
  elsif
84
77
  super(object)
85
78
  end
86
79
  end
87
80
 
81
+ def [](dimension_index)
82
+ @coords[dimension_index]
83
+ end
84
+
88
85
  def ==(object)
89
86
  self.eql? object
90
87
  end
91
88
 
92
89
  def !=(object)
93
- !(self.eql? object)
90
+ not self.eql? object
94
91
  end
95
92
 
96
93
  def inspect
97
- "#<#{self.class}: @maze=#{@maze.inspect}, @x=#{@x}, @y=#{@y}>"
94
+ unless @inspect
95
+ c_index = 0
96
+ coord_list = @coords.map { |c| "@c#{c_index+=1}=#{c}" }
97
+ @inspect = "#<#{self.class}: @maze=#{@maze.inspect}, #{coord_list.join(', ')}>"
98
+ end
99
+ @inspect
98
100
  end
99
101
  end
@@ -7,13 +7,13 @@ class TreeSolver
7
7
  @maze = maze
8
8
  end
9
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)
10
+ def paths(*coords)
11
+ current_cell = @maze.cell *coords
12
+ root_node = current_node = Tree::TreeNode.new(current_cell.coords.map(&:to_s).join(','), current_cell)
13
13
  visited_cells = [current_cell]
14
14
  stack_node = []
15
15
  stack_cell = []
16
- while visited_cells.size != @maze.width * @maze.height
16
+ while visited_cells.size != @maze.total_cells
17
17
  neighbours = current_cell.connected_neighbours
18
18
  unvisited_neighbours = neighbours - visited_cells
19
19
  if unvisited_neighbours.size == 0
@@ -25,7 +25,7 @@ class TreeSolver
25
25
  stack_node += [current_node]*unvisited_neighbours.size
26
26
  end
27
27
  visited_cells << current_cell
28
- new_node = Tree::TreeNode.new("#{current_cell.x},#{current_cell.y}", current_cell)
28
+ new_node = Tree::TreeNode.new(current_cell.coords.map(&:to_s).join(','), current_cell)
29
29
  current_node << new_node
30
30
  current_node = new_node
31
31
  end
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'rmaze'
3
- s.version = '1.5.0'
3
+ s.version = '2.0.0'
4
4
  s.date = '2014-10-01'
5
5
  s.licenses = ["MIT"]
6
6
  s.platform = Gem::Platform::RUBY
@@ -0,0 +1,22 @@
1
+ describe Backtrace do
2
+ it '#initialize' do
3
+ maze = Maze.new(rand(10) + 15, rand(10) + 15)
4
+ backtrace = Backtrace.new maze
5
+ expect(backtrace.maze).to eq(maze)
6
+ end
7
+
8
+ it '#generate 2d' do
9
+ maze = Maze.new(rand(10) + 15, rand(10) + 15)
10
+ backtrace = Backtrace.new maze
11
+ backtrace.generate
12
+ expect(maze.cells.map { |cell| cell.connected? }).to be_all
13
+ end
14
+
15
+ it '#generate Nd' do
16
+ dimensions = ([nil]*(rand(4)+2)).map { |_| 1 + rand(4) }
17
+ maze = Maze.new *dimensions
18
+ backtrace = Backtrace.new maze
19
+ backtrace.generate
20
+ expect(maze.cells.map { |cell| cell.connected? }).to be_all
21
+ end
22
+ end
@@ -1,13 +1,14 @@
1
1
  describe Game do
2
2
  before do
3
- @maze = MazeBTrace.new(8, 8)
4
- @maze.generate
5
- @game = Game.new(@maze)
3
+ @maze = Maze.new 8, 8
4
+ backtrace = Backtrace.new @maze
5
+ backtrace.generate
6
+ @game = Game.new @maze
6
7
  end
7
8
 
8
9
  it '#select_goal_cell' do
9
10
  selected_cell = @game.select_goal_cell(:hard)
10
- expect([selected_cell.x, selected_cell.y]).not_to eq([0, 0])
11
+ expect(selected_cell.coords).not_to eq([0, 0])
11
12
  expect(selected_cell.connected_neighbours.size).to eq(1)
12
13
  end
13
14
 
@@ -16,17 +17,17 @@ describe Game do
16
17
  expect(maze.matrix.flatten).to include(2)
17
18
  end
18
19
 
19
- it '#generate_goal :easy' do
20
+ it '#generate_goal :medium' do
20
21
  maze = @game.generate_goal(:medium)
21
22
  expect(maze.matrix.flatten).to include(2)
22
23
  end
23
24
 
24
- it '#generate_goal :easy' do
25
+ it '#generate_goal :hard' do
25
26
  maze = @game.generate_goal(:hard)
26
27
  expect(maze.matrix.flatten).to include(2)
27
28
  end
28
29
 
29
- it '#generate_goal :easy' do
30
+ it '#generate_goal :random' do
30
31
  maze = @game.generate_goal(:random)
31
32
  expect(maze.matrix.flatten).to include(2)
32
33
  end
@@ -2,46 +2,113 @@ describe MazeCell do
2
2
  before do
3
3
  @width = 4
4
4
  @height = 4
5
- @maze = MazeBTrace.new(@width, @height)
6
- @maze_zero = Maze.new(@width, @height)
5
+ @maze = Maze.new(@width, @height)
7
6
  end
8
7
 
9
8
  it '#initialize' do
9
+ coords = [1, 0]
10
+ indices = @maze.coords_to_indices *coords
11
+ params = indices.clone
12
+ params.push rand(99)
13
+ @maze.set_raw_value *params
10
14
  maze_cell = MazeCell.new(@maze, 1, 0)
11
15
  expect(maze_cell.maze).to eq(@maze)
12
- expect(maze_cell.x).to eq(1)
13
- expect(maze_cell.y).to eq(0)
16
+ expect(maze_cell.coords[0]).to eq(1)
17
+ expect(maze_cell.coords[1]).to eq(0)
18
+ expect(maze_cell.value).to eq(params.last)
14
19
  end
15
20
 
16
- it 'gets directions' do
17
- maze_cell = @maze.cell(0, 0)
18
- expect(maze_cell.left).to be_nil
19
- expect(maze_cell.up).to be_nil
20
- expect(maze_cell.right).to eq(@maze.cell(1, 0))
21
- expect(maze_cell.down).to eq(@maze.cell(0, 1))
21
+ it '#value' do
22
+ coords = [0, 0]
23
+ params = coords.clone
24
+ params.push rand(99)
25
+ @maze.set_value *params
26
+ maze_cell = @maze.cell *coords
27
+ expect(maze_cell.value).to eq(params.last)
22
28
  end
23
29
 
24
- it 'checks wall' do
25
- maze_cell = @maze.cell(0, 0)
26
- expect(maze_cell).to have_wall_left
27
- expect(maze_cell).to have_wall_up
28
- expect(maze_cell).to have_wall_right
29
- expect(maze_cell).to have_wall_down
30
- maze_zero_cell = @maze_zero.cell(1, 1)
31
- expect(maze_zero_cell).not_to have_wall_left
32
- expect(maze_zero_cell).not_to have_wall_up
33
- expect(maze_zero_cell).not_to have_wall_right
34
- expect(maze_zero_cell).not_to have_wall_down
30
+ it '#forward' do
31
+ maze_cell = @maze.cell 1, 1
32
+ expect(maze_cell.forward(0)).to eq(@maze.cell(2, 1))
33
+ expect(maze_cell.forward(1)).to eq(@maze.cell(1, 2))
34
+ end
35
+
36
+ it '#backward' do
37
+ maze_cell = @maze.cell 1, 1
38
+ expect(maze_cell.backward(0)).to eq(@maze.cell(0, 1))
39
+ expect(maze_cell.backward(1)).to eq(@maze.cell(1, 0))
40
+ end
41
+
42
+ it '#has_wall_forward' do
43
+ @maze.set_raw_value_all 1
44
+ coords = [1, 1]
45
+ maze_cell = @maze.cell *coords
46
+ indices = @maze.coords_to_indices *coords
47
+ params = indices.clone
48
+ params[1] += 1
49
+ params.push 0
50
+ @maze.set_raw_value *params
51
+ expect(maze_cell.has_wall_forward(0)).to be_truthy
52
+ expect(maze_cell.has_wall_forward(1)).to be_falsy
53
+ end
54
+
55
+ it '#has_wall_backward' do
56
+ @maze.set_raw_value_all 1
57
+ coords = [1, 1]
58
+ maze_cell = @maze.cell *coords
59
+ indices = @maze.coords_to_indices *coords
60
+ params = indices.clone
61
+ params[1] -= 1
62
+ params.push 0
63
+ @maze.set_raw_value *params
64
+ expect(maze_cell.has_wall_backward(0)).to be_truthy
65
+ expect(maze_cell.has_wall_backward(1)).to be_falsy
66
+ end
67
+
68
+ it '#has_wall_forward on border' do
69
+ @maze.set_raw_value_all 1
70
+ coords = [@maze.dimensions[0] - 1, @maze.dimensions[1] - 1]
71
+ maze_cell = @maze.cell *coords
72
+ expect(maze_cell.has_wall_forward(0)).to be_truthy
73
+ expect(maze_cell.has_wall_forward(1)).to be_truthy
74
+ end
75
+
76
+ it '#has_wall_backward on border' do
77
+ @maze.set_raw_value_all 1
78
+ coords = [0, 0]
79
+ maze_cell = @maze.cell *coords
80
+ expect(maze_cell.has_wall_backward(0)).to be_truthy
81
+ expect(maze_cell.has_wall_backward(1)).to be_truthy
35
82
  end
36
83
 
37
84
  it '#connected?' do
38
- expect(@maze.cell(0, 0)).not_to be_connected
39
- expect(@maze_zero.cell(1, 0)).to be_connected
85
+ coords = [0, 0]
86
+ @maze.set_raw_value_all 0
87
+ maze_cell = @maze.cell *coords
88
+ expect(maze_cell).to be_connected
89
+
90
+ @maze.set_raw_value_all 1
91
+ maze_cell = @maze.cell *coords
92
+ expect(maze_cell).not_to be_connected
93
+
94
+ indices = @maze.coords_to_indices *coords
95
+ params = indices.clone
96
+ params[1] += 1
97
+ params.push 0
98
+ @maze.set_raw_value *params
99
+ expect(maze_cell).to be_connected
40
100
  end
41
101
 
42
- it '#connected_neighbours' do
43
- expect(@maze.cell(0, 0).connected_neighbours).to be_empty
44
- expect(@maze_zero.cell(1, 1).connected_neighbours.size).to eq(4)
102
+ it '#connected? (3x3)' do
103
+ maze = Maze.new 3, 3
104
+ maze.set_raw_value_all 1
105
+ maze_cell1 = maze.cell 1, 1
106
+ maze_cell2 = maze.cell 1, 2
107
+ maze.set_value 1, 1, 0
108
+ maze.set_value 1, 2, 0
109
+ maze.connect_cells maze_cell1, maze_cell2
110
+
111
+ expect(maze_cell1).to be_connected
45
112
  end
46
113
 
47
114
  it '#neighbours' do
@@ -53,6 +120,14 @@ describe MazeCell do
53
120
  expect(neighbours).not_to include(@maze.cell(0, 0))
54
121
  end
55
122
 
123
+ it '#connected_neighbours' do
124
+ @maze.set_raw_value_all 1
125
+ expect(@maze.cell(0, 0).connected_neighbours).to be_empty
126
+
127
+ @maze.set_raw_value_all 0
128
+ expect(@maze.cell(0, 0).connected_neighbours).to eq([@maze.cell(1, 0), @maze.cell(0, 1)])
129
+ end
130
+
56
131
  it '#hash' do
57
132
  allow_any_instance_of(MazeCell).to receive(:eql?).and_return(true) # remove elements only based on hash
58
133
  cells = [@maze.cell(0, 0), @maze.cell(1, 0), @maze.cell(0, 1)]
@@ -82,14 +157,8 @@ describe MazeCell do
82
157
  expect(maze_cell != nil).to be_truthy
83
158
  end
84
159
 
85
- it '#print' do
86
- allow($stdout).to receive(:puts).exactly(3).times
87
- maze_cell = @maze.cell(0, 0)
88
- maze_cell.print
89
- end
90
-
91
160
  it '#inspect' do
92
161
  maze_cell = @maze.cell(1, 0)
93
- expect(maze_cell.inspect).to eq("#<MazeCell: @maze=#{@maze.inspect}, @x=#{1}, @y=#{0}>")
162
+ expect(maze_cell.inspect).to eq("#<MazeCell: @maze=#{@maze.inspect}, @c1=#{1}, @c2=#{0}>")
94
163
  end
95
164
  end
@@ -1,47 +1,223 @@
1
1
  describe Maze do
2
- before do
3
- @width = rand(10) + 15
4
- @height = rand(10) + 15
5
- @maze = Maze.new(@width, @height)
2
+ it '#initialize 2d' do
3
+ width = rand(10) + 15
4
+ height = rand(10) + 15
5
+ maze = Maze.new(width, height)
6
+ expect(maze.dimensions[0]).to eq(width)
7
+ expect(maze.dimensions[1]).to eq(height)
8
+ expect(maze.matrix.length).to eq(width * 2 + 1) # raw dimensions
9
+ expect(maze.matrix[0].length).to eq(height * 2 + 1) # raw dimensions
6
10
  end
7
11
 
8
- it '#initialize' do
9
- expect(@maze.width).to eq(@width)
10
- expect(@maze.height).to eq(@height)
12
+ it '#initialize Nd' do
13
+ dimensions = ([nil]*(rand(10)+3)).map { |_| 1 + rand(4) }
14
+ maze = Maze.new *dimensions
15
+ matrix_iter = maze.matrix
16
+ dimensions.each_with_index do |d, d_index|
17
+ expect(maze.dimensions[d_index]).to eq(dimensions[d_index])
18
+ expect(matrix_iter.length).to eq(dimensions[d_index] * 2 + 1) # raw dimensions
19
+ matrix_iter = matrix_iter[0]
20
+ end
11
21
  end
12
22
 
13
- it '#value' do
14
- expect(@maze.value(0, 0)).to eq(0)
23
+ it '#total_cells 2d' do
24
+ maze = Maze.new 4, 8
25
+ expect(maze.total_cells).to eq(32)
15
26
  end
16
27
 
17
- it '#cell' do
18
- cell = @maze.cell(3, 8)
28
+ it '#total_cells Nd' do
29
+ dimensions = ([nil]*(rand(10)+3)).map { |_| 1 + rand(4) }
30
+ maze = Maze.new *dimensions
31
+ expect(maze.total_cells).to eq(maze.dimensions.reduce(1) { |accum, d| accum*d })
32
+ end
33
+
34
+ it '#total_raw 2d' do
35
+ maze = Maze.new 4, 8
36
+ expect(maze.total_raw).to eq(9*17)
37
+ end
38
+
39
+ it '#cells 2d (0)' do
40
+ maze = Maze.new 2, 2
41
+ expect(maze.cells.length).to eq(4)
42
+ expect(maze.cells).to eq([[0, 0], [0, 1], [1, 0], [1, 1]].map { |coord| maze.cell *coord })
43
+ end
44
+
45
+ it '#cells 2d (1)' do
46
+ maze = Maze.new 5, 4
47
+ expect(maze.cells.length).to eq(20)
48
+ expect(maze.cells).to eq([[0,0],[0,1],[0,2],[0,3],[1,0],[1,1],[1,2],[1,3],[2,0],[2,1],[2,2],[2,3],[3,0],[3,1],[3,2],[3,3],[4,0],[4,1],[4,2],[4,3]].map { |coord| maze.cell *coord })
49
+ end
50
+
51
+ it '#coords_to_indices 2d' do
52
+ maze = Maze.new 4, 8
53
+ x, y = 2, 3
54
+ i, j = maze.coords_to_indices x, y
55
+ expect([i, j]).to eq([5, 7])
56
+ end
57
+
58
+ it '#coords_to_indices 3d' do
59
+ maze = Maze.new 4, 8, 7
60
+ x, y, z = 2, 3, 1
61
+ i, j, k = maze.coords_to_indices x, y, z
62
+ expect([i, j, k]).to eq([5, 7, 3])
63
+ end
64
+
65
+ it '#coords_to_indices Nd' do
66
+ dimensions = ([nil]*(rand(10)+3)).map { |_| 1 + rand(4) }
67
+ maze = Maze.new *dimensions
68
+ coords = dimensions.map { |d| rand(d) }
69
+ indices = maze.coords_to_indices *coords
70
+ expect(indices).to eq(coords.map { |c| 1 + 2 * c })
71
+ end
72
+
73
+ it '#get_raw_value 2d' do
74
+ maze = Maze.new 3, 3
75
+ expect(maze.get_raw_value(0, 0)).to eq(0)
76
+ end
77
+
78
+ it '#get_raw_value Nd' do
79
+ dimensions = ([nil]*(rand(10)+3)).map { |_| 1 + rand(4) }
80
+ maze = Maze.new *dimensions
81
+ coords = dimensions.map { |d| rand(d) }
82
+ indices = maze.coords_to_indices *coords
83
+ expect(maze.get_raw_value(*indices)).to eq(0)
84
+ end
85
+
86
+ it '#set_raw_value 2d' do
87
+ maze = Maze.new 3, 3
88
+ maze.set_raw_value(0, 0, 10)
89
+ expect(maze.get_raw_value(0, 0)).to eq(10)
90
+ maze.set_raw_value(2, 5, 20)
91
+ expect(maze.get_raw_value(2, 5)).to eq(20)
92
+ end
93
+
94
+ it '#set_raw_value Nd' do
95
+ dimensions = ([nil]*(rand(10)+3)).map { |_| 1 + rand(4) }
96
+ maze = Maze.new *dimensions
97
+ coords = dimensions.map { |d| rand(d) }
98
+ value = rand(99) + 1
99
+ indices = maze.coords_to_indices *coords
100
+ params = indices.clone
101
+ params.push value
102
+ maze.set_raw_value *params
103
+ expect(maze.get_raw_value(*indices)).to eq(value)
104
+ end
105
+
106
+ it '#set_raw_value_all 2d' do
107
+ maze = Maze.new 3, 3
108
+ maze.set_raw_value_all 10
109
+ coords = maze.dimensions.map { |d| rand(d) }
110
+ indices = maze.coords_to_indices *coords
111
+ expect(maze.get_raw_value(*indices)).to eq(10)
112
+ end
113
+
114
+ it '#set_raw_value_all Nd' do
115
+ dimensions = ([nil]*(rand(10)+3)).map { |_| 1 + rand(4) }
116
+ maze = Maze.new *dimensions
117
+ maze.set_raw_value_all 11
118
+ coords = maze.dimensions.map { |d| rand(d) }
119
+ indices = maze.coords_to_indices *coords
120
+ expect(maze.get_raw_value(*indices)).to eq(11)
121
+ end
122
+
123
+ it '#get_value 2d' do
124
+ maze = Maze.new 3, 3
125
+ expect(maze.get_value(0, 0)).to eq(0)
126
+ end
127
+
128
+ it '#get_value Nd' do
129
+ dimensions = ([nil]*(rand(10)+3)).map { |_| 1 + rand(4) }
130
+ maze = Maze.new *dimensions
131
+ coords = dimensions.map { |d| rand(d) }
132
+ expect(maze.get_value(*coords)).to eq(0)
133
+ end
134
+
135
+ it '#set_value 2d' do
136
+ maze = Maze.new 3, 3
137
+ maze.set_value(0, 0, 10)
138
+ expect(maze.get_value(0, 0)).to eq(10)
139
+ maze.set_value(2, 1, 20)
140
+ expect(maze.get_value(2, 1)).to eq(20)
141
+ end
142
+
143
+ it '#set_value Nd' do
144
+ dimensions = ([nil]*(rand(10)+3)).map { |_| 1 + rand(4) }
145
+ maze = Maze.new *dimensions
146
+ coords = dimensions.map { |d| rand(d) }
147
+ value = rand(99) + 1
148
+ params = coords.clone
149
+ params.push value
150
+ maze.set_value *params
151
+ expect(maze.get_value(*coords)).to eq(value)
152
+ end
153
+
154
+ it '#cell 2d' do
155
+ maze = Maze.new 4, 9
156
+ cell = maze.cell 3, 8
19
157
  expect(cell).to be_a_kind_of(MazeCell)
20
- expect(cell.maze).to eq(@maze)
21
- expect(cell.x).to eq(3)
22
- expect(cell.y).to eq(8)
158
+ expect(cell.maze).to eq(maze)
159
+ expect(cell[0]).to eq(3)
160
+ expect(cell[1]).to eq(8)
23
161
  end
24
162
 
25
- it '#xy_to_ij' do
26
- x, y = 0, 0
27
- i, j = @maze.xy_to_ij(x, y)
28
- expect([i, j]).to eq([1, 1])
163
+ it '#cell Nd' do
164
+ dimensions = ([nil]*(rand(10)+3)).map { |_| 1 + rand(4) }
165
+ maze = Maze.new *dimensions
166
+ coords = dimensions.map { |d| rand(d) }
167
+ cell = maze.cell *coords
168
+ expect(cell).to be_a_kind_of(MazeCell)
169
+ expect(cell.maze).to eq(maze)
170
+ coords.each_with_index do |c, c_index|
171
+ expect(cell[c_index]).to eq(c)
172
+ end
29
173
  end
30
174
 
31
- it '#generate' do
32
- expect(@maze.generate).to eq(@maze)
175
+ it '#between_cells 2d' do
176
+ maze = Maze.new 4, 8
177
+ cell_a = maze.cell 1, 1
178
+ cell_b = maze.cell 2, 3
179
+ expect(maze.between_cells(cell_a, cell_b)).to eq([4.0, 5.0])
180
+ expect(maze.between_cells(cell_a, cell_a)).to eq([3.0, 3.0])
181
+ end
182
+
183
+ it '#connect_cells 2d' do
184
+ maze = Maze.new 4, 8
185
+ maze.set_raw_value_all 1
186
+ cell_a = maze.cell 1, 1
187
+ cell_b = maze.cell 2, 3
188
+ indices = maze.between_cells cell_a, cell_b
189
+ expect(maze.connect_cells(cell_a, cell_b)).to eq(indices)
190
+ expect(maze.get_raw_value(*indices)).to eq(0)
191
+ end
192
+
193
+ it '#disconnect_cells 2d' do
194
+ maze = Maze.new 4, 8
195
+ maze.set_raw_value_all 0
196
+ cell_a = maze.cell 1, 1
197
+ cell_b = maze.cell 2, 3
198
+ indices = maze.between_cells cell_a, cell_b
199
+ expect(maze.disconnect_cells(cell_a, cell_b)).to eq(indices)
200
+ expect(maze.get_raw_value(*indices)).to eq(1)
201
+ end
202
+
203
+ it '#hash 2d' do
204
+ maze = Maze.new 4, 8
205
+ expect(maze.hash).to eq(48)
33
206
  end
34
207
 
35
- it '#hash' do
36
- expect(@maze.hash).to eq("#{@width}#{@height}".to_i)
208
+ it '#hash Nd' do
209
+ dimensions = ([nil]*(rand(10)+3)).map { |_| 1 + rand(4) }
210
+ maze = Maze.new *dimensions
211
+ expect(maze.hash).to eq(dimensions.reduce(""){ |accum, d| "#{accum}#{d}" }.to_i)
37
212
  end
38
213
 
39
- it '#inspect' do
40
- expect(@maze.inspect).to eq("#<Maze: @width=#{@width}, @height=#{@height}>")
214
+ it '#inspect 2d' do
215
+ maze = Maze.new 3, 6
216
+ expect(maze.inspect).to eq("#<Maze: @d1=3, @d2=6>")
41
217
  end
42
218
 
43
- it '#print' do
44
- allow($stdout).to receive(:puts).exactly(@maze.height_full).times
45
- @maze.print
219
+ it '#inspect 3d' do
220
+ maze = Maze.new 1, 5, 7
221
+ expect(maze.inspect).to eq("#<Maze: @d1=1, @d2=5, @d3=7>")
46
222
  end
47
223
  end
@@ -1,13 +1,23 @@
1
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)
2
+ it '#paths 2d' do
3
+ maze = Maze.new 4, 4
4
+ backtrace = Backtrace.new maze
5
+ backtrace.generate
6
+ tree_solver = TreeSolver.new maze
7
+ paths = tree_solver.paths 0, 0
10
8
  expect(paths.name).to eq('0,0')
11
9
  expect(paths.size).to eq(16)
12
10
  end
11
+
12
+ it '#paths Nd' do
13
+ dimensions = ([nil]*(rand(4)+2)).map { |_| 1 + rand(4) }
14
+ maze = Maze.new *dimensions
15
+ backtrace = Backtrace.new maze
16
+ backtrace.generate
17
+ tree_solver = TreeSolver.new maze
18
+ start_coords = [0]*dimensions.length
19
+ paths = tree_solver.paths *start_coords
20
+ expect(paths.name).to eq(start_coords.map(&:to_s).join(','))
21
+ expect(paths.size).to be > 0
22
+ end
13
23
  end
@@ -1,3 +1,2 @@
1
- require 'simplecov'
2
-
3
- SimpleCov.start
1
+ require 'coveralls'
2
+ Coveralls.wear!
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.5.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pedro Lira
@@ -52,18 +52,19 @@ files:
52
52
  - ".ruby-version"
53
53
  - Gemfile
54
54
  - Gemfile.lock
55
+ - LICENSE.txt
55
56
  - README.md
56
57
  - Rakefile
57
58
  - bin/rmaze
59
+ - lib/algorithm/backtrace.rb
58
60
  - lib/game/game.rb
59
61
  - lib/maze/maze.rb
60
- - lib/maze/maze_btrace.rb
61
62
  - lib/maze/maze_cell.rb
62
63
  - lib/rmaze.rb
63
64
  - lib/solver/tree_solver.rb
64
65
  - rmaze.gemspec
66
+ - spec/algorithm/backtrace_spec.rb
65
67
  - spec/game/game_spec.rb
66
- - spec/maze/maze_btrace_spec.rb
67
68
  - spec/maze/maze_cell_spec.rb
68
69
  - spec/maze/maze_spec.rb
69
70
  - spec/solver/tree_solver_spec.rb
@@ -88,13 +89,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
88
89
  version: '0'
89
90
  requirements: []
90
91
  rubyforge_project:
91
- rubygems_version: 2.4.8
92
+ rubygems_version: 2.4.6
92
93
  signing_key:
93
94
  specification_version: 4
94
95
  summary: RMaze
95
96
  test_files:
97
+ - spec/algorithm/backtrace_spec.rb
96
98
  - spec/game/game_spec.rb
97
- - spec/maze/maze_btrace_spec.rb
98
99
  - spec/maze/maze_cell_spec.rb
99
100
  - spec/maze/maze_spec.rb
100
101
  - spec/solver/tree_solver_spec.rb
@@ -1,57 +0,0 @@
1
- require 'maze/maze'
2
-
3
- class MazeBTrace < Maze
4
- protected
5
- def initialize_matrix
6
- super
7
- make_unconnected
8
- end
9
-
10
- public
11
- def initialize(width, height)
12
- super(width, height)
13
- end
14
-
15
- def between_cells(cell_a, cell_b)
16
- i_a, j_a = xy_to_ij(cell_a.x, cell_a.y)
17
- i_b, j_b = xy_to_ij(cell_b.x, cell_b.y)
18
- [(i_a + i_b).abs / 2, (j_a + j_b).abs / 2]
19
- end
20
-
21
- def generate
22
- super
23
- stack = []
24
- visited_cells = []
25
- all_index_cells = []
26
- current_cell = cell(rand(@width), rand(@height))
27
- visited_cells.push current_cell
28
- (0...@width).each do |x|
29
- (0...@height).each do |y|
30
- all_index_cells << [x, y]
31
- end
32
- end
33
- while visited_cells.size != @width * @height
34
- neighbours = current_cell.neighbours
35
- visited_cells.push current_cell
36
- unvisited_neighbours = (neighbours - visited_cells)
37
- if !unvisited_neighbours.empty?
38
- stack.push current_cell
39
- random_neighbour = unvisited_neighbours.shuffle.shift
40
- i, j = xy_to_ij(random_neighbour.x, random_neighbour.y)
41
- inner_i, inner_j = between_cells(current_cell, random_neighbour)
42
- @matrix[inner_i][inner_j] = 0
43
- current_cell = random_neighbour
44
- visited_cells.push current_cell
45
- elsif !stack.empty?
46
- current_cell = stack.pop
47
- else
48
- unvisited_index_cells = all_index_cells - visited_cells.map { |c| [c.x, c.y] }
49
- unvisited_index_cell = unvisited_index_cells.shuffle.shift
50
- current_cell = cell(unvisited_index_cell[0], unvisited_index_cell[0])
51
- visited_cells.push current_cell
52
- end
53
- visited_cells.uniq!
54
- end
55
- self
56
- end
57
- end
@@ -1,11 +0,0 @@
1
- describe MazeBTrace do
2
- before do
3
- @width = rand(10) + 15
4
- @height = rand(10) + 15
5
- @maze = MazeBTrace.new(@width, @height)
6
- end
7
-
8
- it '#generate' do
9
- expect { @maze.generate }.not_to raise_error
10
- end
11
- end