class AStar
The AStar
class manages the window with the grid and can launch the A* algorithm.
Constants
- DEFAULT_SIZE
Number of squares by lines and columns in the grid.
- HEIGHT_INFO_BLOCK
Height of the informations block in pixels.
- SIZE_GRID
Size of the grid in pixels.
Public Class Methods
new(size=DEFAULT_SIZE)
click to toggle source
Creates the window with its grid.
Calls superclass method
# File lib/astar_visualizer/astar.rb, line 29 def initialize(size=DEFAULT_SIZE) super(SIZE_GRID, SIZE_GRID + HEIGHT_INFO_BLOCK, false) self.caption = 'A* Pathfinding Visualizer' @font = Gosu::Font.new(28) @message = 'Choose the start node.' @grid = Grid.new(self, size, size, SIZE_GRID) @start = @end = nil @needs_reset = false end
Public Instance Methods
a_star()
click to toggle source
Launchs the A* algorithm.
# File lib/astar_visualizer/astar.rb, line 180 def a_star open_set = [@start] came_from = {} g_score = {} f_score = {} @grid.each_node do |node| g_score[node] = Float::INFINITY f_score[node] = Float::INFINITY end g_score[@start] = 0 f_score[@start] = h(@start) until open_set.empty? current = open_set[0] open_set.each do |node| current = node if f_score[node] < f_score[current] end if current == @end reconstruct_path(came_from, current) @message = 'Path found! Press SUPPR to clear the window.' return true end current = open_set.delete_at(open_set.index(current)) current.neighbors.each do |neighbor| tentative_g_score = g_score[current] + 1 next if tentative_g_score >= g_score[neighbor] came_from[neighbor] = current g_score[neighbor] = tentative_g_score f_score[neighbor] = g_score[neighbor] + h(neighbor) unless open_set.include?(neighbor) open_set << neighbor neighbor.open! end end current.closed! if current != @start end @message = 'No path found! Press SUPPR to clear the window.' false end
draw()
click to toggle source
Draws the grid and the informations block.
# File lib/astar_visualizer/astar.rb, line 153 def draw @grid.draw show_info end
find_node()
click to toggle source
Finds the node in the grid corresponding to the mouse position.
# File lib/astar_visualizer/astar.rb, line 98 def find_node @grid.find_node(self.mouse_x, self.mouse_y) end
h(node)
click to toggle source
Heuristic function used : Manhattan distance.
# File lib/astar_visualizer/astar.rb, line 228 def h(node) (node.x - @end.x).abs + (node.y - @end.y).abs end
needs_cursor?()
click to toggle source
To show the mouse cursor on the window.
# File lib/astar_visualizer/astar.rb, line 42 def needs_cursor? true end
ready?()
click to toggle source
Returns if the A* algorithm can be launched.
# File lib/astar_visualizer/astar.rb, line 49 def ready? !@needs_reset && @start && @end end
reconstruct_path(came_from, current)
click to toggle source
Reconstructs the path found by coloring the nodes.
# File lib/astar_visualizer/astar.rb, line 168 def reconstruct_path(came_from, current) while came_from.include?(current) current = came_from[current] current.path! end @start.start! @end.end! end
reset!()
click to toggle source
Resets the window.
# File lib/astar_visualizer/astar.rb, line 70 def reset! reset_start! reset_end! @grid.reset! @needs_reset = false end
reset_end!()
click to toggle source
Resets the end node.
# File lib/astar_visualizer/astar.rb, line 63 def reset_end! @end = nil end
reset_start!()
click to toggle source
Resets the start node.
# File lib/astar_visualizer/astar.rb, line 56 def reset_start! @start = nil end
show_info()
click to toggle source
Shows the informations block.
# File lib/astar_visualizer/astar.rb, line 161 def show_info @font.draw_text(@message, 10, SIZE_GRID + 8, 5) end
update()
click to toggle source
Updates the window. If the mouse buttons are used, it updates nodes and the message in the informations block.
# File lib/astar_visualizer/astar.rb, line 106 def update return if @needs_reset # Message if !@start @message = 'Choose the start node.' elsif !@end @message = 'Choose the end node.' else @message = 'Add obstacles and press ENTER.' end if Gosu.button_down? Gosu::MsLeft node = find_node if node # Make start node if !@start && node != @end node.start! @start = node # Make end node elsif !@end && node != @start node.end! @end = node # Make obstacle elsif node != @start && node != @end node.obstacle! end end end # Clear a node if Gosu.button_down? Gosu::MsRight node = find_node if node node.reset! if node == @start reset_start! elsif node == @end reset_end! end end end end