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 +1 -1
- data/bin/mazegen +16 -3
- data/lib/willb-mazegen/cellgraph.rb +8 -4
- data/lib/willb-mazegen/maze.rb +69 -16
- data/lib/willb-mazegen/mazerenderer.rb +10 -2
- metadata +41 -18
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.1.0
|
data/bin/mazegen
CHANGED
@@ -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
|
-
|
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
|
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]}).
|
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)}).
|
73
|
+
Hash[*nodenums.zip(nodenums.map {|num| gen_neighbors(num)}).flatten_once]
|
70
74
|
end
|
71
75
|
|
72
76
|
def nodenums
|
data/lib/willb-mazegen/maze.rb
CHANGED
@@ -1,9 +1,12 @@
|
|
1
1
|
# maze.rb is licensed under the Apache Software License, version 2.0
|
2
|
-
# and
|
2
|
+
# and Copyright (c) 2010 William Benton (http://willbenton.com)
|
3
3
|
|
4
|
-
|
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
|
-
@
|
56
|
-
@
|
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
|
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.
|
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
|
-
|
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:
|
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
|
-
|
18
|
-
|
19
|
-
|
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
|
-
|
35
|
+
type: :development
|
36
|
+
version_requirements: *id001
|
25
37
|
- !ruby/object:Gem::Dependency
|
26
38
|
name: prawn
|
27
|
-
|
28
|
-
|
29
|
-
|
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
|
-
|
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
|
-
|
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.
|
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
|
-
|
86
|
-
- spec/spec_helper.rb
|
108
|
+
test_files: []
|
109
|
+
|