amaze 0.2.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 +7 -0
- data/.gitignore +9 -0
- data/.rspec +2 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +110 -0
- data/Rakefile +6 -0
- data/amaze.gemspec +30 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/exe/amaze +5 -0
- data/lib/amaze.rb +17 -0
- data/lib/amaze/algorithm.rb +44 -0
- data/lib/amaze/algorithm/aldous_border.rb +36 -0
- data/lib/amaze/algorithm/binary_tree.rb +20 -0
- data/lib/amaze/algorithm/growing_tree.rb +52 -0
- data/lib/amaze/algorithm/hunt_and_kill.rb +53 -0
- data/lib/amaze/algorithm/recursive_backtracker.rb +77 -0
- data/lib/amaze/algorithm/sidewinder.rb +42 -0
- data/lib/amaze/algorithm/wilson.rb +54 -0
- data/lib/amaze/cell.rb +63 -0
- data/lib/amaze/cell/hex.rb +10 -0
- data/lib/amaze/cell/octo.rb +10 -0
- data/lib/amaze/cell/polar.rb +16 -0
- data/lib/amaze/cell/square.rb +10 -0
- data/lib/amaze/distances.rb +53 -0
- data/lib/amaze/factory.rb +153 -0
- data/lib/amaze/formatter.rb +5 -0
- data/lib/amaze/formatter/ascii.rb +91 -0
- data/lib/amaze/formatter/ascii/delta.rb +180 -0
- data/lib/amaze/formatter/ascii/ortho.rb +105 -0
- data/lib/amaze/formatter/ascii/polar.rb +199 -0
- data/lib/amaze/formatter/ascii/sigma.rb +213 -0
- data/lib/amaze/formatter/ascii/upsilon.rb +281 -0
- data/lib/amaze/formatter/image.rb +127 -0
- data/lib/amaze/formatter/image/delta.rb +123 -0
- data/lib/amaze/formatter/image/ortho.rb +103 -0
- data/lib/amaze/formatter/image/polar.rb +173 -0
- data/lib/amaze/formatter/image/sigma.rb +122 -0
- data/lib/amaze/formatter/image/upsilon.rb +135 -0
- data/lib/amaze/grid.rb +66 -0
- data/lib/amaze/grid/delta.rb +87 -0
- data/lib/amaze/grid/ortho.rb +38 -0
- data/lib/amaze/grid/polar.rb +61 -0
- data/lib/amaze/grid/sigma.rb +61 -0
- data/lib/amaze/grid/upsilon.rb +74 -0
- data/lib/amaze/mask.rb +75 -0
- data/lib/amaze/masked_grid.rb +29 -0
- data/lib/amaze/script.rb +361 -0
- data/lib/amaze/shape.rb +23 -0
- data/lib/amaze/shape/diamond.rb +26 -0
- data/lib/amaze/shape/hexagon.rb +79 -0
- data/lib/amaze/shape/star.rb +114 -0
- data/lib/amaze/shape/triangle.rb +25 -0
- data/lib/amaze/version.rb +3 -0
- data/support/characters.txt +17 -0
- data/support/mask/mask1.txt +10 -0
- data/support/mask/mask2.txt +12 -0
- data/support/mask/mask3.txt +15 -0
- metadata +203 -0
@@ -0,0 +1,122 @@
|
|
1
|
+
|
2
|
+
class Amaze::Formatter::Image::Sigma < Amaze::Formatter::Image
|
3
|
+
|
4
|
+
def render_background
|
5
|
+
canvas.stroke_antialias true
|
6
|
+
canvas.stroke_linecap 'square'
|
7
|
+
canvas.stroke 'none'
|
8
|
+
grid.each_cell do |cell|
|
9
|
+
color = distance_color cell
|
10
|
+
next unless color
|
11
|
+
canvas.fill color
|
12
|
+
x1, x2, x3, x4, y1, y2, y3 = coord cell
|
13
|
+
canvas.polygon x2, y1, x3, y1, x4, y2, x3, y3, x2, y3, x1, y2
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def render_grid
|
18
|
+
canvas.stroke_antialias true
|
19
|
+
canvas.stroke_linecap 'round'
|
20
|
+
canvas.stroke_linejoin 'round'
|
21
|
+
canvas.stroke 'gray90'
|
22
|
+
canvas.stroke_width 1
|
23
|
+
canvas.fill 'none'
|
24
|
+
|
25
|
+
grid.each_cell do |cell|
|
26
|
+
x1, x2, x3, x4, y1, y2, y3 = coord cell
|
27
|
+
canvas.polygon x2, y1, x3, y1, x4, y2, x3, y3, x2, y3, x1, y2
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def render_wall
|
32
|
+
canvas.stroke_antialias true
|
33
|
+
canvas.stroke_linecap 'round'
|
34
|
+
canvas.stroke_linejoin 'round'
|
35
|
+
canvas.stroke wall_color
|
36
|
+
canvas.stroke_width wall_width
|
37
|
+
canvas.fill 'none'
|
38
|
+
|
39
|
+
grid.each_cell do |cell|
|
40
|
+
x1, x2, x3, x4, y1, y2, y3 = coord cell
|
41
|
+
|
42
|
+
canvas.line x2, y1, x3, y1 unless cell.linked_to?(:north)
|
43
|
+
canvas.line x3, y1, x4, y2 unless cell.linked_to?(:northeast)
|
44
|
+
canvas.line x4, y2, x3, y3 unless cell.linked_to?(:southeast)
|
45
|
+
canvas.line x2, y3, x3, y3 unless cell.linked_to?(:south)
|
46
|
+
canvas.line x1, y2, x2, y3 unless cell.linked_to?(:southwest)
|
47
|
+
canvas.line x1, y2, x2, y1 unless cell.linked_to?(:northwest)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def render_path
|
52
|
+
canvas.stroke_antialias true
|
53
|
+
canvas.stroke_linecap 'round'
|
54
|
+
canvas.stroke_linejoin 'round'
|
55
|
+
canvas.fill 'none'
|
56
|
+
canvas.stroke path_color
|
57
|
+
canvas.stroke_width path_width
|
58
|
+
|
59
|
+
grid.each_cell do |cell|
|
60
|
+
next unless path_cell? cell
|
61
|
+
|
62
|
+
x1, y1 = center_coord cell
|
63
|
+
%i( northeast southeast south ).each do |direction|
|
64
|
+
next unless path?(direction, cell)
|
65
|
+
x2, y2 = center_coord cell.send(direction)
|
66
|
+
canvas.line x1, y1, x2, y2
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# draw start and finish
|
71
|
+
canvas.stroke_antialias true
|
72
|
+
canvas.stroke_linecap 'round'
|
73
|
+
canvas.fill path_color
|
74
|
+
canvas.stroke 'none'
|
75
|
+
[path_start, path_finish].compact.each do |cell|
|
76
|
+
x, y = center_coord cell
|
77
|
+
canvas.ellipse x, y, path_width*2, path_width*2, 0, 360
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def coord cell
|
82
|
+
x, y = center_coord cell
|
83
|
+
|
84
|
+
x1 = x - cell_width
|
85
|
+
x2 = x - cell_width / 2.0
|
86
|
+
x3 = x + cell_width / 2.0
|
87
|
+
x4 = x + cell_width
|
88
|
+
|
89
|
+
y1 = y - pattern_height / 2.0
|
90
|
+
y2 = y
|
91
|
+
y3 = y + pattern_height / 2.0
|
92
|
+
|
93
|
+
[x1, x2, x3, x4, y1, y2, y3]
|
94
|
+
end
|
95
|
+
|
96
|
+
def center_coord cell
|
97
|
+
row, column = cell.row, cell.column
|
98
|
+
|
99
|
+
x = column * pattern_width + cell_width + cell_offset
|
100
|
+
# add half or full height to find center
|
101
|
+
row_offset = column.even? ? 0.5 : 1.0
|
102
|
+
y = (row+row_offset) * pattern_height + cell_offset
|
103
|
+
|
104
|
+
[x, y]
|
105
|
+
end
|
106
|
+
|
107
|
+
def pattern_width
|
108
|
+
@pattern_width ||= cell_width * 3 / 2.0
|
109
|
+
end
|
110
|
+
|
111
|
+
def pattern_height
|
112
|
+
@pattern_height ||= cell_width * Math.sqrt(3)
|
113
|
+
end
|
114
|
+
|
115
|
+
def image_width
|
116
|
+
pattern_width * grid.columns + cell_width / 2.0 + wall_width + border_width * 2 + 1
|
117
|
+
end
|
118
|
+
|
119
|
+
def image_height
|
120
|
+
pattern_height * grid.rows + pattern_height / 2.0 + wall_width + border_width * 2 + 1
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,135 @@
|
|
1
|
+
|
2
|
+
class Amaze::Formatter::Image::Upsilon < Amaze::Formatter::Image
|
3
|
+
|
4
|
+
def render_background
|
5
|
+
canvas.stroke_antialias true
|
6
|
+
canvas.stroke_linecap 'round'
|
7
|
+
canvas.stroke_linejoin 'round'
|
8
|
+
canvas.stroke 'none'
|
9
|
+
grid.each_cell do |cell|
|
10
|
+
color = distance_color cell
|
11
|
+
next unless color
|
12
|
+
canvas.fill color
|
13
|
+
canvas.polygon *coord(cell)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def render_grid
|
18
|
+
canvas.stroke_antialias true
|
19
|
+
canvas.stroke_linecap 'round'
|
20
|
+
canvas.stroke_linejoin 'round'
|
21
|
+
canvas.stroke 'gray90'
|
22
|
+
canvas.stroke_width 1
|
23
|
+
canvas.fill 'none'
|
24
|
+
|
25
|
+
grid.each_cell do |cell|
|
26
|
+
canvas.polygon *coord(cell)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def render_wall
|
31
|
+
canvas.stroke_antialias true
|
32
|
+
canvas.stroke_linecap 'round'
|
33
|
+
canvas.stroke_linejoin 'round'
|
34
|
+
canvas.stroke wall_color
|
35
|
+
canvas.stroke_width wall_width
|
36
|
+
canvas.fill 'none'
|
37
|
+
|
38
|
+
grid.each_cell do |cell|
|
39
|
+
ax, ay, bx, by, cx, cy, dx, dy, ex, ey, fx, fy, gx, gy, hx, hy = coord cell
|
40
|
+
|
41
|
+
if (cell.row + cell.column).even?
|
42
|
+
# octo cells
|
43
|
+
canvas.line ax, ay, bx, by unless cell.linked_to?(:north)
|
44
|
+
canvas.line bx, by, cx, cy unless cell.linked_to?(:northeast)
|
45
|
+
canvas.line cx, cy, dx, dy unless cell.linked_to?(:east)
|
46
|
+
canvas.line dx, dy, ex, ey unless cell.linked_to?(:southeast)
|
47
|
+
canvas.line ex, ey, fx, fy unless cell.linked_to?(:south)
|
48
|
+
canvas.line fx, fy, gx, gy unless cell.linked_to?(:southwest)
|
49
|
+
canvas.line gx, gy, hx, hy unless cell.linked_to?(:west)
|
50
|
+
canvas.line hx, hy, ax, ay unless cell.linked_to?(:northwest)
|
51
|
+
else
|
52
|
+
# square cells
|
53
|
+
canvas.line ax, ay, bx, by unless cell.linked_to?(:north)
|
54
|
+
canvas.line bx, by, cx, cy unless cell.linked_to?(:east)
|
55
|
+
canvas.line cx, cy, dx, dy unless cell.linked_to?(:south)
|
56
|
+
canvas.line dx, dy, ax, ay unless cell.linked_to?(:west)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def render_path
|
62
|
+
canvas.stroke_antialias true
|
63
|
+
canvas.stroke_linecap 'round'
|
64
|
+
canvas.stroke_linejoin 'round'
|
65
|
+
canvas.fill 'none'
|
66
|
+
canvas.stroke path_color
|
67
|
+
canvas.stroke_width path_width
|
68
|
+
|
69
|
+
grid.each_cell do |cell|
|
70
|
+
next unless path_cell? cell
|
71
|
+
|
72
|
+
x1, y1 = center_coord cell
|
73
|
+
%i( north northeast east southeast ).each do |direction|
|
74
|
+
# square cells don't respond to northeast and southeast
|
75
|
+
next unless cell.respond_to? direction
|
76
|
+
next unless path?(direction, cell)
|
77
|
+
x2, y2 = center_coord cell.send(direction)
|
78
|
+
canvas.line x1, y1, x2, y2
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# draw start and finish
|
83
|
+
canvas.stroke_antialias true
|
84
|
+
canvas.stroke_linecap 'round'
|
85
|
+
canvas.fill path_color
|
86
|
+
canvas.stroke 'none'
|
87
|
+
[path_start, path_finish].compact.each do |cell|
|
88
|
+
x, y = center_coord cell
|
89
|
+
canvas.ellipse x, y, path_width*2, path_width*2, 0, 360
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def coord cell
|
94
|
+
row, column = cell.row, cell.column
|
95
|
+
|
96
|
+
x1 = column * pattern_width + cell_offset
|
97
|
+
x2 = x1 + partial_cell
|
98
|
+
x3 = x2 + cell_width
|
99
|
+
x4 = x3 + partial_cell
|
100
|
+
|
101
|
+
y1 = row * pattern_width + cell_offset
|
102
|
+
y2 = y1 + partial_cell
|
103
|
+
y3 = y2 + cell_width
|
104
|
+
y4 = y3 + partial_cell
|
105
|
+
|
106
|
+
if (row+column).even?
|
107
|
+
[x2, y1, x3, y1, x4, y2, x4, y3, x3, y4, x2, y4, x1, y3, x1, y2]
|
108
|
+
else
|
109
|
+
[x2, y2, x3, y2, x3, y3, x2, y3]
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def center_coord cell
|
114
|
+
row, column = cell.row, cell.column
|
115
|
+
|
116
|
+
d = partial_cell + cell_width / 2.0
|
117
|
+
x = column * pattern_width + d + cell_offset
|
118
|
+
y = row * pattern_width + d + cell_offset
|
119
|
+
[x, y]
|
120
|
+
end
|
121
|
+
|
122
|
+
def partial_cell
|
123
|
+
@partial_cell ||= cell_width * Math.sqrt(2) / 2.0
|
124
|
+
end
|
125
|
+
|
126
|
+
def pattern_width
|
127
|
+
@pattern_width ||= cell_width + partial_cell
|
128
|
+
end
|
129
|
+
|
130
|
+
def image_width
|
131
|
+
pattern_width * (grid.columns) + partial_cell + wall_width + border_width * 2 + 1
|
132
|
+
end
|
133
|
+
|
134
|
+
alias_method :image_height, :image_width
|
135
|
+
end
|
data/lib/amaze/grid.rb
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
|
2
|
+
class Amaze::Grid
|
3
|
+
autoload :Ortho, 'amaze/grid/ortho'
|
4
|
+
autoload :Delta, 'amaze/grid/delta'
|
5
|
+
autoload :Sigma, 'amaze/grid/sigma'
|
6
|
+
autoload :Upsilon, 'amaze/grid/upsilon'
|
7
|
+
autoload :Polar, 'amaze/grid/polar'
|
8
|
+
|
9
|
+
# The dimension of the amaze
|
10
|
+
attr_reader :rows, :columns
|
11
|
+
|
12
|
+
# The grid
|
13
|
+
attr_reader :grid
|
14
|
+
|
15
|
+
def initialize rows, columns
|
16
|
+
@rows = rows
|
17
|
+
@columns = columns
|
18
|
+
|
19
|
+
prepare_grid
|
20
|
+
configure_cell
|
21
|
+
end
|
22
|
+
|
23
|
+
def prepare_grid
|
24
|
+
raise NotImplementedError
|
25
|
+
end
|
26
|
+
|
27
|
+
def configure_cell
|
28
|
+
raise NotImplementedError
|
29
|
+
end
|
30
|
+
|
31
|
+
def [](row, column)
|
32
|
+
return nil unless row.between?(0, rows-1)
|
33
|
+
return nil unless column.between?(0, columns-1)
|
34
|
+
grid[row][column]
|
35
|
+
end
|
36
|
+
|
37
|
+
def each_row
|
38
|
+
grid.each do |row|
|
39
|
+
yield row
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def each_cell
|
44
|
+
each_row do |row|
|
45
|
+
row.each do |cell|
|
46
|
+
yield cell if cell
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def random_cell
|
52
|
+
self[rand(rows), rand(columns)]
|
53
|
+
end
|
54
|
+
|
55
|
+
def deadends
|
56
|
+
list = []
|
57
|
+
each_cell do |cell|
|
58
|
+
list << cell if cell.links.size == 1
|
59
|
+
end
|
60
|
+
list
|
61
|
+
end
|
62
|
+
|
63
|
+
def size
|
64
|
+
rows * columns
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
|
2
|
+
class Amaze::Grid::Delta < Amaze::Grid
|
3
|
+
|
4
|
+
def prepare_grid
|
5
|
+
@grid = Array.new(rows) do |row|
|
6
|
+
Array.new(columns) do |column|
|
7
|
+
# Use the square cells, since the neighbors are the same
|
8
|
+
Amaze::Cell::Square.new row, column
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def configure_cell
|
14
|
+
each_cell do |cell|
|
15
|
+
row, column = cell.row, cell.column
|
16
|
+
|
17
|
+
cell.east = self[row, column+1]
|
18
|
+
cell.west = self[row, column-1]
|
19
|
+
|
20
|
+
if (row+column).even?
|
21
|
+
cell.north = self[row-1, column]
|
22
|
+
else
|
23
|
+
cell.south = self[row+1, column]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
__END__
|
30
|
+
|
31
|
+
__ __
|
32
|
+
\* /\ /\
|
33
|
+
\/__\/__\
|
34
|
+
/\ /\ /
|
35
|
+
/__\/__\/
|
36
|
+
\ /\ /\
|
37
|
+
\/__\/__\
|
38
|
+
/\ /\ /
|
39
|
+
/__\/__\/
|
40
|
+
|
41
|
+
______ ______ ______
|
42
|
+
\ /\ /\ /
|
43
|
+
\ * / \ / \ /
|
44
|
+
\ / * \ / \ /
|
45
|
+
\/______\/______\/
|
46
|
+
/\ /\ /\
|
47
|
+
/ \ / \ / \
|
48
|
+
/ \ / \ / \
|
49
|
+
/______\/______\/______\
|
50
|
+
\ /\ /\ /
|
51
|
+
\ / \ / \ /
|
52
|
+
\ / \ / \ /
|
53
|
+
\/______\/______\/
|
54
|
+
/\ /\ /\
|
55
|
+
/ \ / \ / \
|
56
|
+
/ \ / \ / \
|
57
|
+
/______\/______\/______\
|
58
|
+
\ /\ /\ /
|
59
|
+
\ / \ / \ /
|
60
|
+
\ / \ / \ /
|
61
|
+
\/______\/______\/
|
62
|
+
|
63
|
+
__________ __________ __________
|
64
|
+
\ /\ /\ /
|
65
|
+
\ / \ / \ /
|
66
|
+
\ * / \ / \ /
|
67
|
+
\ / * \ / \ /
|
68
|
+
\ / \ / \ /
|
69
|
+
\/__________\/__________\/
|
70
|
+
/\ /\ /\
|
71
|
+
/ \ / \ / \
|
72
|
+
/ \ / \ / \
|
73
|
+
/ \ / \ / \
|
74
|
+
/ \ / \ / \
|
75
|
+
/__________\/__________\/__________\
|
76
|
+
\ /\ /\ /
|
77
|
+
\ / \ / \ /
|
78
|
+
\ / \ / \ /
|
79
|
+
\ / \ / \ /
|
80
|
+
\ / \ / \ /
|
81
|
+
\/__________\/__________\/
|
82
|
+
/\ /\ /\
|
83
|
+
/ \ / \ / \
|
84
|
+
/ \ / \ / \
|
85
|
+
/ \ / \ / \
|
86
|
+
/ \ / \ / \
|
87
|
+
/__________\/__________\/__________\
|
@@ -0,0 +1,38 @@
|
|
1
|
+
|
2
|
+
class Amaze::Grid::Ortho < Amaze::Grid
|
3
|
+
|
4
|
+
def prepare_grid
|
5
|
+
@grid = Array.new(rows) do |row|
|
6
|
+
Array.new(columns) do |column|
|
7
|
+
Amaze::Cell::Square.new row, column
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def configure_cell
|
13
|
+
each_cell do |cell|
|
14
|
+
row, column = cell.row, cell.column
|
15
|
+
|
16
|
+
cell.north = self[row-1, column]
|
17
|
+
cell.east = self[row, column+1]
|
18
|
+
cell.south = self[row+1, column]
|
19
|
+
cell.west = self[row, column-1]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
__END__
|
25
|
+
|
26
|
+
+---+---+
|
27
|
+
| | |
|
28
|
+
+---+---+
|
29
|
+
| | |
|
30
|
+
+---+---+
|
31
|
+
|
32
|
+
+------+------+
|
33
|
+
| | |
|
34
|
+
| | |
|
35
|
+
+------+------+
|
36
|
+
| | |
|
37
|
+
| | |
|
38
|
+
+------+------+
|