astar_visualizer 0.0.1
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/LICENSE +21 -0
- data/README.md +52 -0
- data/astar_visualizer.gemspec +35 -0
- data/bin/astar-visualizer +18 -0
- data/lib/astar_visualizer.rb +5 -0
- data/lib/astar_visualizer/astar.rb +231 -0
- data/lib/astar_visualizer/grid.rb +134 -0
- data/lib/astar_visualizer/node.rb +154 -0
- metadata +72 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 39837dbd735e9048db8a9e1f5a919722b8e6c8acadeee1dd5c40f6bfca756e86
|
4
|
+
data.tar.gz: eca57add44720b859d36dcfd56c632ccf1599286b421306fadacbe3271389ea1
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ce8f2847926c6776c061a2092e661af8f715fc7ac4c14403b9db1cdd609a4878735254f44c98087eb82f5d940bf4a843ea45225a8b34bc75842e90e03cee5c01
|
7
|
+
data.tar.gz: b1ec1e53196d19fe2cb57c9528d9ab9c4f9cd8aff9bbfb29aa4cd18ec5185f8b69f9b2ada4c272e37fcd45e68812f595866a4f2795584d4092a99229a3caaa69
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2020 Quentin DESCHAMPS
|
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
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
# A* Visualizer
|
2
|
+
|
3
|
+
**A* Visualizer** is an interactive application to visualize the
|
4
|
+
[A* pathfinding algorithm](https://en.wikipedia.org/wiki/A*_search_algorithm)
|
5
|
+
in a grid with obstacles. The heuristic function used is the
|
6
|
+
[Manhattan distance](https://en.wikipedia.org/wiki/Taxicab_geometry).
|
7
|
+
|
8
|
+
It uses the [Gosu](https://github.com/gosu/gosu) game development library.
|
9
|
+
|
10
|
+

|
11
|
+
|
12
|
+
## Install
|
13
|
+
To install this ruby gem, use the `gem` command:
|
14
|
+
```
|
15
|
+
gem install astar_visualizer
|
16
|
+
```
|
17
|
+
|
18
|
+
## Usage
|
19
|
+
To launch the A* Visualizer, use this command:
|
20
|
+
```
|
21
|
+
astar-visualizer
|
22
|
+
```
|
23
|
+
|
24
|
+
You can also use the `irb` environment:
|
25
|
+
```ruby
|
26
|
+
require 'astar_visualizer'
|
27
|
+
AStar.new.show
|
28
|
+
```
|
29
|
+
|
30
|
+
You can also choose the size of the grid:
|
31
|
+
```
|
32
|
+
astar-visualizer SIZE
|
33
|
+
```
|
34
|
+
SIZE must be a number between 10 and 100 (default: 50).
|
35
|
+
|
36
|
+
It will open a window with the grid. Then:
|
37
|
+
|
38
|
+
1. Left click on a node to choose the start node.
|
39
|
+
2. Left click on another node to choose the end node.
|
40
|
+
3. Left click on nodes to put obstacles. Right click on them if you want to remove them.
|
41
|
+
4. Press *ENTER* to launch the A* algorithm. If a path is found, the path is colored in yellow and the visited nodes in cyan.
|
42
|
+
5. Press *SUPPR* to clear the window.
|
43
|
+
|
44
|
+
## Links
|
45
|
+
- GitHub: https://github.com/Quentin18/astar-visualizer
|
46
|
+
- RubyGems: https://rubygems.org/gems/astar_visualizer
|
47
|
+
|
48
|
+
## Author
|
49
|
+
[Quentin Deschamps](mailto:quentindeschamps18@gmail.com)
|
50
|
+
|
51
|
+
## License
|
52
|
+
[MIT](https://choosealicense.com/licenses/mit/)
|
@@ -0,0 +1,35 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'astar_visualizer'
|
3
|
+
s.version = '0.0.1'
|
4
|
+
s.license = 'MIT'
|
5
|
+
s.summary = 'A* pathfinding visualizer using Gosu'
|
6
|
+
s.description = <<-DESCRIPTION
|
7
|
+
A* Visualizer is an interactive application to visualize
|
8
|
+
the A* pathfinding algorithm in a grid with obstacles.
|
9
|
+
It uses the Gosu game development library.
|
10
|
+
DESCRIPTION
|
11
|
+
s.author = 'Quentin Deschamps'
|
12
|
+
s.email = 'quentindeschamps18@gmail.com'
|
13
|
+
s.homepage = 'https://github.com/Quentin18/astar-visualizer'
|
14
|
+
|
15
|
+
s.add_runtime_dependency 'gosu', '~> 0.15.2'
|
16
|
+
s.require_paths = ['lib']
|
17
|
+
s.files = [
|
18
|
+
'bin/astar-visualizer',
|
19
|
+
'lib/astar_visualizer.rb',
|
20
|
+
'lib/astar_visualizer/astar.rb',
|
21
|
+
'lib/astar_visualizer/grid.rb',
|
22
|
+
'lib/astar_visualizer/node.rb',
|
23
|
+
'LICENSE',
|
24
|
+
'README.md',
|
25
|
+
'astar_visualizer.gemspec'
|
26
|
+
]
|
27
|
+
|
28
|
+
s.bindir = 'bin'
|
29
|
+
s.executables << 'astar-visualizer'
|
30
|
+
|
31
|
+
s.rdoc_options = ['--main', 'README.md']
|
32
|
+
s.extra_rdoc_files = ['LICENSE', 'README.md']
|
33
|
+
|
34
|
+
s.post_install_message = 'Thanks for installing! Run this command: astar-visualizer'
|
35
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'astar_visualizer'
|
4
|
+
MIN_SIZE = 10
|
5
|
+
MAX_SIZE = 100
|
6
|
+
|
7
|
+
if ARGV.empty?
|
8
|
+
window = AStar.new
|
9
|
+
else
|
10
|
+
size = ARGV.first.to_i
|
11
|
+
if size < MIN_SIZE || size > MAX_SIZE
|
12
|
+
puts "Please choose a size between #{MIN_SIZE} and #{MAX_SIZE}."
|
13
|
+
return
|
14
|
+
end
|
15
|
+
window = AStar.new(size)
|
16
|
+
end
|
17
|
+
|
18
|
+
window.show
|
@@ -0,0 +1,231 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# File: astar.rb
|
5
|
+
# Author: Quentin Deschamps
|
6
|
+
# Date: August 2020
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'gosu'
|
10
|
+
require 'astar_visualizer/grid'
|
11
|
+
|
12
|
+
#
|
13
|
+
# The AStar class manages the window with the grid and can launch
|
14
|
+
# the A* algorithm.
|
15
|
+
#
|
16
|
+
class AStar < Gosu::Window
|
17
|
+
# Size of the grid in pixels.
|
18
|
+
SIZE_GRID = 700
|
19
|
+
|
20
|
+
# Height of the informations block in pixels.
|
21
|
+
HEIGHT_INFO_BLOCK = 40
|
22
|
+
|
23
|
+
# Number of squares by lines and columns in the grid.
|
24
|
+
DEFAULT_SIZE = 50
|
25
|
+
|
26
|
+
#
|
27
|
+
# Creates the window with its grid.
|
28
|
+
#
|
29
|
+
def initialize(size=DEFAULT_SIZE)
|
30
|
+
super(SIZE_GRID, SIZE_GRID + HEIGHT_INFO_BLOCK, false)
|
31
|
+
self.caption = 'A* Pathfinding Visualizer'
|
32
|
+
@font = Gosu::Font.new(28)
|
33
|
+
@message = 'Choose the start node.'
|
34
|
+
@grid = Grid.new(self, size, size, SIZE_GRID)
|
35
|
+
@start = @end = nil
|
36
|
+
@needs_reset = false
|
37
|
+
end
|
38
|
+
|
39
|
+
#
|
40
|
+
# To show the mouse cursor on the window.
|
41
|
+
#
|
42
|
+
def needs_cursor?
|
43
|
+
true
|
44
|
+
end
|
45
|
+
|
46
|
+
#
|
47
|
+
# Returns if the A* algorithm can be launched.
|
48
|
+
#
|
49
|
+
def ready?
|
50
|
+
!@needs_reset && @start && @end
|
51
|
+
end
|
52
|
+
|
53
|
+
#
|
54
|
+
# Resets the start node.
|
55
|
+
#
|
56
|
+
def reset_start!
|
57
|
+
@start = nil
|
58
|
+
end
|
59
|
+
|
60
|
+
#
|
61
|
+
# Resets the end node.
|
62
|
+
#
|
63
|
+
def reset_end!
|
64
|
+
@end = nil
|
65
|
+
end
|
66
|
+
|
67
|
+
#
|
68
|
+
# Resets the window.
|
69
|
+
#
|
70
|
+
def reset!
|
71
|
+
reset_start!
|
72
|
+
reset_end!
|
73
|
+
@grid.reset!
|
74
|
+
@needs_reset = false
|
75
|
+
end
|
76
|
+
|
77
|
+
#
|
78
|
+
# Gets the button down. Two different actions:
|
79
|
+
#
|
80
|
+
# * *ENTER*: launch A* algorithm
|
81
|
+
# * *SUPPR*: clear window
|
82
|
+
#
|
83
|
+
def button_down(id)
|
84
|
+
# ENTER: launch A* algorithm
|
85
|
+
if id == Gosu::KbReturn && ready?
|
86
|
+
@grid.update_neighbors
|
87
|
+
a_star
|
88
|
+
@needs_reset = true
|
89
|
+
end
|
90
|
+
|
91
|
+
# SUPPR: clear window
|
92
|
+
reset! if id == Gosu::KbDelete
|
93
|
+
end
|
94
|
+
|
95
|
+
#
|
96
|
+
# Finds the node in the grid corresponding to the mouse position.
|
97
|
+
#
|
98
|
+
def find_node
|
99
|
+
@grid.find_node(self.mouse_x, self.mouse_y)
|
100
|
+
end
|
101
|
+
|
102
|
+
#
|
103
|
+
# Updates the window. If the mouse buttons are used, it updates nodes and
|
104
|
+
# the message in the informations block.
|
105
|
+
#
|
106
|
+
def update
|
107
|
+
return if @needs_reset
|
108
|
+
|
109
|
+
# Message
|
110
|
+
if !@start
|
111
|
+
@message = 'Choose the start node.'
|
112
|
+
elsif !@end
|
113
|
+
@message = 'Choose the end node.'
|
114
|
+
else
|
115
|
+
@message = 'Add obstacles and press ENTER.'
|
116
|
+
end
|
117
|
+
|
118
|
+
if Gosu.button_down? Gosu::MsLeft
|
119
|
+
node = find_node
|
120
|
+
if node
|
121
|
+
# Make start node
|
122
|
+
if !@start && node != @end
|
123
|
+
node.start!
|
124
|
+
@start = node
|
125
|
+
# Make end node
|
126
|
+
elsif !@end && node != @start
|
127
|
+
node.end!
|
128
|
+
@end = node
|
129
|
+
# Make obstacle
|
130
|
+
elsif node != @start && node != @end
|
131
|
+
node.obstacle!
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
# Clear a node
|
137
|
+
if Gosu.button_down? Gosu::MsRight
|
138
|
+
node = find_node
|
139
|
+
if node
|
140
|
+
node.reset!
|
141
|
+
if node == @start
|
142
|
+
reset_start!
|
143
|
+
elsif node == @end
|
144
|
+
reset_end!
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
#
|
151
|
+
# Draws the grid and the informations block.
|
152
|
+
#
|
153
|
+
def draw
|
154
|
+
@grid.draw
|
155
|
+
show_info
|
156
|
+
end
|
157
|
+
|
158
|
+
#
|
159
|
+
# Shows the informations block.
|
160
|
+
#
|
161
|
+
def show_info
|
162
|
+
@font.draw_text(@message, 10, SIZE_GRID + 8, 5)
|
163
|
+
end
|
164
|
+
|
165
|
+
#
|
166
|
+
# Reconstructs the path found by coloring the nodes.
|
167
|
+
#
|
168
|
+
def reconstruct_path(came_from, current)
|
169
|
+
while came_from.include?(current)
|
170
|
+
current = came_from[current]
|
171
|
+
current.path!
|
172
|
+
end
|
173
|
+
@start.start!
|
174
|
+
@end.end!
|
175
|
+
end
|
176
|
+
|
177
|
+
#
|
178
|
+
# Launchs the A* algorithm.
|
179
|
+
#
|
180
|
+
def a_star
|
181
|
+
open_set = [@start]
|
182
|
+
came_from = {}
|
183
|
+
g_score = {}
|
184
|
+
f_score = {}
|
185
|
+
@grid.each_node do |node|
|
186
|
+
g_score[node] = Float::INFINITY
|
187
|
+
f_score[node] = Float::INFINITY
|
188
|
+
end
|
189
|
+
g_score[@start] = 0
|
190
|
+
f_score[@start] = h(@start)
|
191
|
+
|
192
|
+
until open_set.empty?
|
193
|
+
current = open_set[0]
|
194
|
+
open_set.each do |node|
|
195
|
+
current = node if f_score[node] < f_score[current]
|
196
|
+
end
|
197
|
+
|
198
|
+
if current == @end
|
199
|
+
reconstruct_path(came_from, current)
|
200
|
+
@message = 'Path found! Press SUPPR to clear the window.'
|
201
|
+
return true
|
202
|
+
end
|
203
|
+
|
204
|
+
current = open_set.delete_at(open_set.index(current))
|
205
|
+
|
206
|
+
current.neighbors.each do |neighbor|
|
207
|
+
tentative_g_score = g_score[current] + 1
|
208
|
+
next if tentative_g_score >= g_score[neighbor]
|
209
|
+
|
210
|
+
came_from[neighbor] = current
|
211
|
+
g_score[neighbor] = tentative_g_score
|
212
|
+
f_score[neighbor] = g_score[neighbor] + h(neighbor)
|
213
|
+
unless open_set.include?(neighbor)
|
214
|
+
open_set << neighbor
|
215
|
+
neighbor.open!
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
current.closed! if current != @start
|
220
|
+
end
|
221
|
+
@message = 'No path found! Press SUPPR to clear the window.'
|
222
|
+
false
|
223
|
+
end
|
224
|
+
|
225
|
+
#
|
226
|
+
# Heuristic function used : Manhattan distance.
|
227
|
+
#
|
228
|
+
def h(node)
|
229
|
+
(node.x - @end.x).abs + (node.y - @end.y).abs
|
230
|
+
end
|
231
|
+
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# File: grid.rb
|
5
|
+
# Author: Quentin Deschamps
|
6
|
+
# Date: August 2020
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'gosu'
|
10
|
+
require 'astar_visualizer/node'
|
11
|
+
|
12
|
+
#
|
13
|
+
# The Grid class represents the grid. It is composed of nodes.
|
14
|
+
#
|
15
|
+
class Grid
|
16
|
+
#
|
17
|
+
# Builds the nodes of the grid. It returns the list of nodes.
|
18
|
+
#
|
19
|
+
def self.build_nodes(window, cols, rows, width, height)
|
20
|
+
nodes = []
|
21
|
+
rows.times do |y|
|
22
|
+
nodes << []
|
23
|
+
cols.times do |x|
|
24
|
+
nodes[y] << Node.new(window, x, y, width, height)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
nodes
|
28
|
+
end
|
29
|
+
|
30
|
+
#
|
31
|
+
# Creates the grid with the nodes.
|
32
|
+
#
|
33
|
+
def initialize(window, cols, rows, size)
|
34
|
+
@window = window
|
35
|
+
@cols = cols
|
36
|
+
@rows = rows
|
37
|
+
@width = size / cols # width of a node's square
|
38
|
+
@height = size / rows # height of a node's square
|
39
|
+
@nodes = Grid.build_nodes(window, cols, rows, @width, @height)
|
40
|
+
@color = Gosu::Color.argb(0xaad3d3d3)
|
41
|
+
end
|
42
|
+
|
43
|
+
#
|
44
|
+
# Returns a node from the grid.
|
45
|
+
#
|
46
|
+
def node(x, y)
|
47
|
+
@nodes[y][x]
|
48
|
+
end
|
49
|
+
|
50
|
+
#
|
51
|
+
# Yields all nodes of the grid.
|
52
|
+
#
|
53
|
+
def each_node
|
54
|
+
@rows.times do |y|
|
55
|
+
@cols.times do |x|
|
56
|
+
yield node(x, y)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
#
|
62
|
+
# Returns if the (x, y) position is in the grid.
|
63
|
+
#
|
64
|
+
def inside?(x, y)
|
65
|
+
x >= 0 && x < @cols && y >= 0 && y < @rows
|
66
|
+
end
|
67
|
+
|
68
|
+
#
|
69
|
+
# Returns if a node is walkable.
|
70
|
+
#
|
71
|
+
def walkable?(x, y)
|
72
|
+
inside?(x, y) && !node(x, y).obstacle?
|
73
|
+
end
|
74
|
+
|
75
|
+
#
|
76
|
+
# Updates the neighbors of all nodes.
|
77
|
+
#
|
78
|
+
def update_neighbors
|
79
|
+
each_node do |node|
|
80
|
+
x = node.x
|
81
|
+
y = node.y
|
82
|
+
node.neighbors.clear
|
83
|
+
node.add_to_neighbors(node(x, y - 1)) if walkable?(x, y - 1) # ↑
|
84
|
+
node.add_to_neighbors(node(x + 1, y)) if walkable?(x + 1, y) # →
|
85
|
+
node.add_to_neighbors(node(x, y + 1)) if walkable?(x, y + 1) # ↓
|
86
|
+
node.add_to_neighbors(node(x - 1, y)) if walkable?(x - 1, y) # ←
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
#
|
91
|
+
# Resets all the nodes.
|
92
|
+
#
|
93
|
+
def reset!
|
94
|
+
each_node(&:reset!)
|
95
|
+
end
|
96
|
+
|
97
|
+
#
|
98
|
+
# Draws the lines of the grid.
|
99
|
+
#
|
100
|
+
def draw_grid
|
101
|
+
@rows.times do |i| # horizontal
|
102
|
+
x1 = 0
|
103
|
+
y1 = @height * i
|
104
|
+
x2 = @width * @cols
|
105
|
+
y2 = @height * i
|
106
|
+
@window.draw_line(x1, y1, @color, x2, y2, @color)
|
107
|
+
end
|
108
|
+
@cols.times do |i| # vertical
|
109
|
+
x1 = @width * i
|
110
|
+
y1 = 0
|
111
|
+
x2 = @width * i
|
112
|
+
y2 = @height * @rows
|
113
|
+
@window.draw_line(x1, y1, @color, x2, y2, @color)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
#
|
118
|
+
# Draws the nodes and the grid.
|
119
|
+
#
|
120
|
+
def draw
|
121
|
+
each_node(&:draw)
|
122
|
+
draw_grid
|
123
|
+
end
|
124
|
+
|
125
|
+
#
|
126
|
+
# Finds a node in the grid using mouse position.
|
127
|
+
#
|
128
|
+
def find_node(mouse_x, mouse_y)
|
129
|
+
each_node do |node|
|
130
|
+
return node if node.inside?(mouse_x, mouse_y)
|
131
|
+
end
|
132
|
+
nil
|
133
|
+
end
|
134
|
+
end
|
@@ -0,0 +1,154 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# File: node.rb
|
5
|
+
# Author: Quentin Deschamps
|
6
|
+
# Date: August 2020
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'gosu'
|
10
|
+
|
11
|
+
#
|
12
|
+
# The Node class represents the squares of the grid.
|
13
|
+
#
|
14
|
+
class Node
|
15
|
+
# Gets the x position in the grid.
|
16
|
+
attr_reader :x
|
17
|
+
|
18
|
+
# Gets the y position in the grid.
|
19
|
+
attr_reader :y
|
20
|
+
|
21
|
+
# Gets the neighbors (list of nodes).
|
22
|
+
attr_reader :neighbors
|
23
|
+
|
24
|
+
#
|
25
|
+
# Creates a node. It is composed of the (x, y) position in the grid and the
|
26
|
+
# neighbors (list of nodes).
|
27
|
+
#
|
28
|
+
def initialize(window, x, y, width, height)
|
29
|
+
@@colors ||= {
|
30
|
+
green: Gosu::Color.argb(0xff00ff00),
|
31
|
+
red: Gosu::Color.argb(0xffff0000),
|
32
|
+
grey: Gosu::Color.argb(0xff808080),
|
33
|
+
lightcyan: Gosu::Color.argb(0xffe0ffff),
|
34
|
+
cyan: Gosu::Color.argb(0xff00ffff),
|
35
|
+
white: Gosu::Color.argb(0xffffffff),
|
36
|
+
yellow: Gosu::Color.argb(0xffffff00),
|
37
|
+
}
|
38
|
+
@@window ||= window
|
39
|
+
@x = x
|
40
|
+
@y = y
|
41
|
+
@width = width
|
42
|
+
@height = height
|
43
|
+
@color = @@colors[:white]
|
44
|
+
@neighbors = []
|
45
|
+
end
|
46
|
+
|
47
|
+
#
|
48
|
+
# Returns if the node is the start point (green color).
|
49
|
+
#
|
50
|
+
def start?
|
51
|
+
@color == @@colors[:green]
|
52
|
+
end
|
53
|
+
|
54
|
+
#
|
55
|
+
# Makes a node the start point (green color).
|
56
|
+
#
|
57
|
+
def start!
|
58
|
+
@color = @@colors[:green]
|
59
|
+
end
|
60
|
+
|
61
|
+
#
|
62
|
+
# Returns if the node is the end point (red color).
|
63
|
+
#
|
64
|
+
def end?
|
65
|
+
@color == @@colors[:red]
|
66
|
+
end
|
67
|
+
|
68
|
+
#
|
69
|
+
# Makes a node the end point (red color).
|
70
|
+
#
|
71
|
+
def end!
|
72
|
+
@color = @@colors[:red]
|
73
|
+
end
|
74
|
+
|
75
|
+
#
|
76
|
+
# Returns if the node is an obstacle (grey color).
|
77
|
+
#
|
78
|
+
def obstacle?
|
79
|
+
@color == @@colors[:grey]
|
80
|
+
end
|
81
|
+
|
82
|
+
#
|
83
|
+
# Makes a node an obstacle (grey color).
|
84
|
+
#
|
85
|
+
def obstacle!
|
86
|
+
@color = @@colors[:grey]
|
87
|
+
end
|
88
|
+
|
89
|
+
#
|
90
|
+
# Returns if the node is in the open list (cyan color).
|
91
|
+
#
|
92
|
+
def open?
|
93
|
+
@color == @@colors[:cyan]
|
94
|
+
end
|
95
|
+
|
96
|
+
#
|
97
|
+
# Makes a node like in the open list (cyan color).
|
98
|
+
#
|
99
|
+
def open!
|
100
|
+
@color = @@colors[:cyan]
|
101
|
+
end
|
102
|
+
|
103
|
+
#
|
104
|
+
# Returns if the node is in the closed list (lightcyan color).
|
105
|
+
#
|
106
|
+
def closed?
|
107
|
+
@color == @@colors[:lightcyan]
|
108
|
+
end
|
109
|
+
|
110
|
+
#
|
111
|
+
# Makes a node like in the closed list (lightcyan color).
|
112
|
+
#
|
113
|
+
def closed!
|
114
|
+
@color = @@colors[:lightcyan]
|
115
|
+
end
|
116
|
+
|
117
|
+
#
|
118
|
+
# Resets a node (white color).
|
119
|
+
#
|
120
|
+
def reset!
|
121
|
+
@color = @@colors[:white]
|
122
|
+
end
|
123
|
+
|
124
|
+
#
|
125
|
+
# Makes a node in the found path (yellow color).
|
126
|
+
#
|
127
|
+
def path!
|
128
|
+
@color = @@colors[:yellow]
|
129
|
+
end
|
130
|
+
|
131
|
+
#
|
132
|
+
# Draws the square.
|
133
|
+
#
|
134
|
+
def draw
|
135
|
+
@@window.draw_rect(@x * @width, @y * @height, @width, @height, @color)
|
136
|
+
end
|
137
|
+
|
138
|
+
#
|
139
|
+
# Returns if the mouse position is in the square.
|
140
|
+
#
|
141
|
+
def inside?(mouse_x, mouse_y)
|
142
|
+
pos_x = @x * @width
|
143
|
+
pos_y = @y * @height
|
144
|
+
mouse_x >= pos_x && mouse_x <= pos_x + @width && \
|
145
|
+
mouse_y >= pos_y && mouse_y <= pos_y + @height
|
146
|
+
end
|
147
|
+
|
148
|
+
#
|
149
|
+
# Adds a node to the neighbors list.
|
150
|
+
#
|
151
|
+
def add_to_neighbors(node)
|
152
|
+
@neighbors << node
|
153
|
+
end
|
154
|
+
end
|
metadata
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: astar_visualizer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Quentin Deschamps
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-08-11 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: gosu
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.15.2
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.15.2
|
27
|
+
description: |2
|
28
|
+
A* Visualizer is an interactive application to visualize
|
29
|
+
the A* pathfinding algorithm in a grid with obstacles.
|
30
|
+
It uses the Gosu game development library.
|
31
|
+
email: quentindeschamps18@gmail.com
|
32
|
+
executables:
|
33
|
+
- astar-visualizer
|
34
|
+
extensions: []
|
35
|
+
extra_rdoc_files:
|
36
|
+
- LICENSE
|
37
|
+
- README.md
|
38
|
+
files:
|
39
|
+
- LICENSE
|
40
|
+
- README.md
|
41
|
+
- astar_visualizer.gemspec
|
42
|
+
- bin/astar-visualizer
|
43
|
+
- lib/astar_visualizer.rb
|
44
|
+
- lib/astar_visualizer/astar.rb
|
45
|
+
- lib/astar_visualizer/grid.rb
|
46
|
+
- lib/astar_visualizer/node.rb
|
47
|
+
homepage: https://github.com/Quentin18/astar-visualizer
|
48
|
+
licenses:
|
49
|
+
- MIT
|
50
|
+
metadata: {}
|
51
|
+
post_install_message: 'Thanks for installing! Run this command: astar-visualizer'
|
52
|
+
rdoc_options:
|
53
|
+
- "--main"
|
54
|
+
- README.md
|
55
|
+
require_paths:
|
56
|
+
- lib
|
57
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '0'
|
67
|
+
requirements: []
|
68
|
+
rubygems_version: 3.0.3
|
69
|
+
signing_key:
|
70
|
+
specification_version: 4
|
71
|
+
summary: A* pathfinding visualizer using Gosu
|
72
|
+
test_files: []
|