willb-mazegen 0.0.0 → 0.1.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.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.0
1
+ 0.1.0
@@ -28,19 +28,25 @@ cellsize = PAGE_WIDTH / DEFAULT_WIDTH
28
28
 
29
29
  page_count = 1
30
30
 
31
+ algorithms = {"prim"=>MazePrim, "easy-dfs"=>MazeEasyDFS, "dfs"=>MazeDFS, "rb"=>MazeDFS}
32
+ algorithm = MazeDFS
33
+
31
34
  op = OptionParser.new do |opts|
32
35
  opts.banner = "Usage: mazegen [options] outfile.pdf"
33
36
 
34
37
  opts.on("-w", "--width COLS", "width of maze in cells (defaults to 67)") do |w|
35
38
  width = w.to_i
36
- cellsize = PAGE_WIDTH / width
37
- height = PAGE_HEIGHT / cellsize
39
+ cellsize = PAGE_WIDTH.to_f / width
40
+ height = (PAGE_HEIGHT / cellsize).to_i
38
41
  end
39
42
 
40
43
  opts.on("-p", "--pagecount NUM", "number of mazes to put in the output document") do |p|
41
44
  page_count = p.to_i
42
45
  end
43
46
 
47
+ opts.on("-a", "--algorithm ALGO", "algorithm for maze generation (#{algorithms.keys.join(", ")}; default is dfs)") do |alg|
48
+ algorithm = algorithms[alg.downcase]
49
+ end
44
50
  end
45
51
 
46
52
  begin
@@ -56,7 +62,14 @@ if ARGV.size < 1
56
62
  exit
57
63
  end
58
64
 
59
- m = Maze.new(width, height)
65
+ if algorithm == nil
66
+ puts "You must pick a valid maze generation algorithm."
67
+ puts "Valid algorithms are #{algorithms.keys.join(", ")}."
68
+ puts op
69
+ exit
70
+ end
71
+
72
+ m = algorithm.new(width, height)
60
73
 
61
74
  Prawn::Document.generate(ARGV[0]) do
62
75
  while page_count > 0
@@ -1,5 +1,5 @@
1
1
  # cellgraph.rb is licensed under the Apache Software License, version 2.0
2
- # and copyright (c) 2010 William Benton (http://willbenton.com)
2
+ # and Copyright (c) 2010 William Benton (http://willbenton.com)
3
3
 
4
4
  # An undirected, unweighted graph of cells on a square grid; edges
5
5
  # indicate spaces, non-edges (between neighbors) indicate walls
@@ -23,7 +23,11 @@ class CellGraph
23
23
  end
24
24
 
25
25
  alias add_edge add_edges
26
-
26
+
27
+ def size
28
+ return x * y
29
+ end
30
+
27
31
  def edges_from(node)
28
32
  @node_edges[node].map {|dest| [node, dest]}
29
33
  end
@@ -56,7 +60,7 @@ class CellGraph
56
60
 
57
61
  private
58
62
  def init_coords
59
- Hash[*nodenums.zip(nodenums.map {|num| [num % @x, num / @x]}).flatten(1)]
63
+ Hash[*nodenums.zip(nodenums.map {|num| [num % @x, num / @x]}).flatten_once]
60
64
  end
61
65
 
62
66
  def init_edges
@@ -66,7 +70,7 @@ class CellGraph
66
70
  end
67
71
 
68
72
  def init_neighbors
69
- Hash[*nodenums.zip(nodenums.map {|num| gen_neighbors(num)}).flatten(1)]
73
+ Hash[*nodenums.zip(nodenums.map {|num| gen_neighbors(num)}).flatten_once]
70
74
  end
71
75
 
72
76
  def nodenums
@@ -1,9 +1,12 @@
1
1
  # maze.rb is licensed under the Apache Software License, version 2.0
2
- # and copyright (c) 2010 William Benton (http://willbenton.com)
2
+ # and Copyright (c) 2010 William Benton (http://willbenton.com)
3
3
 
4
- class Maze
4
+ # common infrastructure
5
+ module MazeBase
5
6
  def initialize(x,y)
6
7
  @cg = CellGraph.new(x,y)
8
+ @startcell = 0
9
+ @endcell = (@cg.x * @cg.y) - 1
7
10
  end
8
11
 
9
12
  attr_reader :cg
@@ -12,18 +15,6 @@ class Maze
12
15
  [@cg.x,@cg.y]
13
16
  end
14
17
 
15
- def gen
16
- reset
17
- while @walls.size > 0
18
- source,dest = @walls.delete_at(rand(@walls.size))
19
- unless @maze_cells.include? dest
20
- @maze_cells << dest
21
- @cg.add_edge(source=>dest)
22
- @walls = @walls + walls_for(dest)
23
- end
24
- end
25
- end
26
-
27
18
  def walls_for(cell)
28
19
  @cg.neighbors(cell).map {|nbc| [cell,nbc]} - @cg.edges_from(cell)
29
20
  end
@@ -44,16 +35,78 @@ class Maze
44
35
 
45
36
  result
46
37
  end
38
+ end
39
+
40
+ # Prim algorithm maze generator
41
+ class MazePrim
42
+ include MazeBase
47
43
 
44
+ def gen
45
+ reset
46
+ while @walls.size > 0
47
+ source,dest = @walls.delete_at(rand(@walls.size))
48
+ unless @maze_cells.include? dest
49
+ @maze_cells << dest
50
+ @cg.add_edge(source=>dest)
51
+ @walls = @walls + walls_for(dest)
52
+ end
53
+ end
54
+ end
55
+
48
56
  private
49
57
  def reset
50
58
  @cg.reset_edges
51
59
 
52
60
  @maze_cells = (Set.new << 0)
53
61
  @walls = walls_for(0)
62
+ end
63
+ end
64
+
65
+ # recursive-backtracking DFS maze generator
66
+ class MazeDFS
67
+ include MazeBase
68
+
69
+ def gen
70
+ reset
71
+ gen_from(first_cell)
72
+ end
73
+
74
+ private
75
+ def first_cell
76
+ rand(cg.x * cg.y)
77
+ end
78
+
79
+ def reset
80
+ @cg.reset_edges
54
81
 
55
- @startcell = 0
56
- @endcell = (@cg.x * @cg.y) - 1
82
+ @maze_cells = SortedSet.new
83
+ @neighbor_set = Hash.new {|h,cell| h[cell] = @cg.neighbors(cell).reject {|x| @maze_cells.include?(x)}; h[cell]}
84
+ end
85
+
86
+ def gen_from(initial_cell)
87
+ worklist = [initial_cell]
88
+ while not worklist.empty?
89
+ cell = worklist.last
90
+ my_neighbor_set = @neighbor_set[cell]
91
+
92
+ if my_neighbor_set.empty?
93
+ worklist.pop
94
+ unless worklist.empty?
95
+ @neighbor_set[worklist.last].reject! {|x| @maze_cells.include?(x)}
96
+ end
97
+ else
98
+ dest = my_neighbor_set.delete_at(rand(my_neighbor_set.size))
99
+ @cg.add_edge(cell=>dest)
100
+ worklist << dest
101
+ @maze_cells << dest
102
+ end
103
+ end
57
104
  end
58
105
  end
59
106
 
107
+ class MazeEasyDFS < MazeDFS
108
+ private
109
+ def first_cell
110
+ @startcell
111
+ end
112
+ end
@@ -1,5 +1,13 @@
1
1
  # mazerenderer.rb is licensed under the Apache Software License, version 2.0
2
- # and copyright (c) 2010 William Benton (http://willbenton.com)
2
+ # and Copyright (c) 2010 William Benton (http://willbenton.com)
3
+
4
+ class Array
5
+ def flatten_once
6
+ self.inject([]) do |acc, val|
7
+ val.is_a?(Array) ? acc.concat(val) : acc << val
8
+ end
9
+ end
10
+ end
3
11
 
4
12
  class MazeRenderer
5
13
  def initialize(m, cellsize)
@@ -34,6 +42,6 @@ class MazeRenderer
34
42
  private
35
43
  def gen_corners(x,y)
36
44
  pairs = {:ul=>[x,y],:ur=>[x+1,y],:bl=>[x,y+1],:br=>[x+1,y+1]}.map {|key,val| [key,val.map{|p| p * @cellsize}]}
37
- Hash[*pairs.flatten(1)]
45
+ Hash[*pairs.flatten_once]
38
46
  end
39
47
  end
metadata CHANGED
@@ -1,7 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: willb-mazegen
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ hash: 27
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
5
11
  platform: ruby
6
12
  authors:
7
13
  - Will Benton
@@ -9,29 +15,41 @@ autorequire:
9
15
  bindir: bin
10
16
  cert_chain: []
11
17
 
12
- date: 2010-02-06 00:00:00 -06:00
18
+ date: 2012-07-06 00:00:00 -05:00
13
19
  default_executable: mazegen
14
20
  dependencies:
15
21
  - !ruby/object:Gem::Dependency
16
22
  name: rspec
17
- type: :development
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
20
26
  requirements:
21
27
  - - ">="
22
28
  - !ruby/object:Gem::Version
29
+ hash: 13
30
+ segments:
31
+ - 1
32
+ - 2
33
+ - 9
23
34
  version: 1.2.9
24
- version:
35
+ type: :development
36
+ version_requirements: *id001
25
37
  - !ruby/object:Gem::Dependency
26
38
  name: prawn
27
- type: :runtime
28
- version_requirement:
29
- version_requirements: !ruby/object:Gem::Requirement
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
30
42
  requirements:
31
43
  - - ">="
32
44
  - !ruby/object:Gem::Version
45
+ hash: 3
46
+ segments:
47
+ - 0
48
+ - 7
49
+ - 0
33
50
  version: 0.7.0
34
- version:
51
+ type: :runtime
52
+ version_requirements: *id002
35
53
  description: Simple PDF maze generator, based on spanning trees. Can generate one or many mazes of different complexities.
36
54
  email: willbenton@gmail.com
37
55
  executables:
@@ -58,29 +76,34 @@ homepage: http://github.com/willb/mazegen
58
76
  licenses: []
59
77
 
60
78
  post_install_message:
61
- rdoc_options:
62
- - --charset=UTF-8
79
+ rdoc_options: []
80
+
63
81
  require_paths:
64
82
  - lib
65
83
  required_ruby_version: !ruby/object:Gem::Requirement
84
+ none: false
66
85
  requirements:
67
86
  - - ">="
68
87
  - !ruby/object:Gem::Version
88
+ hash: 3
89
+ segments:
90
+ - 0
69
91
  version: "0"
70
- version:
71
92
  required_rubygems_version: !ruby/object:Gem::Requirement
93
+ none: false
72
94
  requirements:
73
95
  - - ">="
74
96
  - !ruby/object:Gem::Version
97
+ hash: 3
98
+ segments:
99
+ - 0
75
100
  version: "0"
76
- version:
77
101
  requirements: []
78
102
 
79
103
  rubyforge_project:
80
- rubygems_version: 1.3.5
104
+ rubygems_version: 1.3.7
81
105
  signing_key:
82
106
  specification_version: 3
83
107
  summary: Simple PDF maze generator
84
- test_files:
85
- - spec/mazegen_spec.rb
86
- - spec/spec_helper.rb
108
+ test_files: []
109
+