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.
Files changed (61) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +4 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.txt +21 -0
  7. data/README.md +110 -0
  8. data/Rakefile +6 -0
  9. data/amaze.gemspec +30 -0
  10. data/bin/console +15 -0
  11. data/bin/setup +8 -0
  12. data/exe/amaze +5 -0
  13. data/lib/amaze.rb +17 -0
  14. data/lib/amaze/algorithm.rb +44 -0
  15. data/lib/amaze/algorithm/aldous_border.rb +36 -0
  16. data/lib/amaze/algorithm/binary_tree.rb +20 -0
  17. data/lib/amaze/algorithm/growing_tree.rb +52 -0
  18. data/lib/amaze/algorithm/hunt_and_kill.rb +53 -0
  19. data/lib/amaze/algorithm/recursive_backtracker.rb +77 -0
  20. data/lib/amaze/algorithm/sidewinder.rb +42 -0
  21. data/lib/amaze/algorithm/wilson.rb +54 -0
  22. data/lib/amaze/cell.rb +63 -0
  23. data/lib/amaze/cell/hex.rb +10 -0
  24. data/lib/amaze/cell/octo.rb +10 -0
  25. data/lib/amaze/cell/polar.rb +16 -0
  26. data/lib/amaze/cell/square.rb +10 -0
  27. data/lib/amaze/distances.rb +53 -0
  28. data/lib/amaze/factory.rb +153 -0
  29. data/lib/amaze/formatter.rb +5 -0
  30. data/lib/amaze/formatter/ascii.rb +91 -0
  31. data/lib/amaze/formatter/ascii/delta.rb +180 -0
  32. data/lib/amaze/formatter/ascii/ortho.rb +105 -0
  33. data/lib/amaze/formatter/ascii/polar.rb +199 -0
  34. data/lib/amaze/formatter/ascii/sigma.rb +213 -0
  35. data/lib/amaze/formatter/ascii/upsilon.rb +281 -0
  36. data/lib/amaze/formatter/image.rb +127 -0
  37. data/lib/amaze/formatter/image/delta.rb +123 -0
  38. data/lib/amaze/formatter/image/ortho.rb +103 -0
  39. data/lib/amaze/formatter/image/polar.rb +173 -0
  40. data/lib/amaze/formatter/image/sigma.rb +122 -0
  41. data/lib/amaze/formatter/image/upsilon.rb +135 -0
  42. data/lib/amaze/grid.rb +66 -0
  43. data/lib/amaze/grid/delta.rb +87 -0
  44. data/lib/amaze/grid/ortho.rb +38 -0
  45. data/lib/amaze/grid/polar.rb +61 -0
  46. data/lib/amaze/grid/sigma.rb +61 -0
  47. data/lib/amaze/grid/upsilon.rb +74 -0
  48. data/lib/amaze/mask.rb +75 -0
  49. data/lib/amaze/masked_grid.rb +29 -0
  50. data/lib/amaze/script.rb +361 -0
  51. data/lib/amaze/shape.rb +23 -0
  52. data/lib/amaze/shape/diamond.rb +26 -0
  53. data/lib/amaze/shape/hexagon.rb +79 -0
  54. data/lib/amaze/shape/star.rb +114 -0
  55. data/lib/amaze/shape/triangle.rb +25 -0
  56. data/lib/amaze/version.rb +3 -0
  57. data/support/characters.txt +17 -0
  58. data/support/mask/mask1.txt +10 -0
  59. data/support/mask/mask2.txt +12 -0
  60. data/support/mask/mask3.txt +15 -0
  61. 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
@@ -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
+ +------+------+