rmaze 1.5.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
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