Class: AStarFinder
- Inherits:
-
Object
- Object
- AStarFinder
- Defined in:
- lib/pathfinding/finder/astar.rb
Overview
A* path-finder.
Instance Method Summary collapse
-
#d(n1, n2) ⇒ Object
Returns the distance between two nodes.
-
#find_path(start_node, end_node, grid) ⇒ Object
Finds and returns the path as a list of node objects.
-
#initialize(heuristic = Heuristic::method(:manhattan), diagonal_movement = DiagonalMovement::NEVER) ⇒ AStarFinder
constructor
Initializes the A* path-finder.
-
#reconstruct_path(came_from, current) ⇒ Object
Reconstructs the path from the current node.
Constructor Details
#initialize(heuristic = Heuristic::method(:manhattan), diagonal_movement = DiagonalMovement::NEVER) ⇒ AStarFinder
Initializes the A* path-finder. Params:
-
heuristic: heuristic function (see theHeuristicmodule) -
diagonal_movement: set diagonal movements (see theDiagonalMovementmodule)
21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/pathfinding/finder/astar.rb', line 21 def initialize( heuristic = Heuristic::method(:manhattan), diagonal_movement = DiagonalMovement::NEVER ) @diagonal_movement = diagonal_movement if diagonal_movement == DiagonalMovement::NEVER @heuristic = heuristic else @heuristic = Heuristic::method(:octile) end end |
Instance Method Details
#d(n1, n2) ⇒ Object
Returns the distance between two nodes.
79 80 81 |
# File 'lib/pathfinding/finder/astar.rb', line 79 def d(n1, n2) (n1.x == n2.x || n1.y == n2.y) ? 1 : Math.sqrt(2) end |
#find_path(start_node, end_node, grid) ⇒ Object
Finds and returns the path as a list of node objects.
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 |
# File 'lib/pathfinding/finder/astar.rb', line 36 def find_path(start_node, end_node, grid) open_set = [start_node] 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_node] = 0 f_score[start_node] = @heuristic.call( (start_node.x - end_node.x).abs, (start_node.y - end_node.y).abs) 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_node return reconstruct_path(came_from, current) end current = open_set.delete_at(open_set.index(current)) grid.neighbors(current, @diagonal_movement).each do |neighbor| tentative_g_score = g_score[current] + d(current, neighbor) next if tentative_g_score >= g_score[neighbor] came_from[neighbor] = current g_score[neighbor] = tentative_g_score f_score[neighbor] = g_score[neighbor] + @heuristic.call( (neighbor.x - end_node.x).abs, (neighbor.y - end_node.y).abs) unless open_set.include?(neighbor) open_set << neighbor end end end end |
#reconstruct_path(came_from, current) ⇒ Object
Reconstructs the path from the current node.
86 87 88 89 90 91 92 93 |
# File 'lib/pathfinding/finder/astar.rb', line 86 def reconstruct_path(came_from, current) total_path = [current] while came_from.include?(current) current = came_from[current] total_path << current end total_path.reverse end |