# General graph node
class Node
+ # Type of the others nodes in the `graph`
type N: Node
# parent graph
private var open: Bool = false
# Main functionnality, returns path from `self` to `dest`
- fun path_to(dest: N, max_cost: Int, context: PathContext): nullable Path[N]
+ fun path_to(dest: N, max_cost: Int, context: PathContext): nullable AStarPath[N]
do
return path_to_alts(dest, max_cost, context, null)
end
# Find a path to a possible `destination` or a node accepted by `alt_targets`
fun path_to_alts(destination: nullable N, max_cost: Int, context: PathContext,
- alt_targets: nullable TargetCondition[N]): nullable Path[N]
+ alt_targets: nullable TargetCondition[N]): nullable AStarPath[N]
do
var cost = 0
loop
var frontier_node: nullable N = null
- var bucket_searched: Int = 0
+ var bucket_searched = 0
# find next valid node in frontier/buckets
loop
else if frontier_node == destination or
(alt_targets != null and alt_targets.accept(frontier_node)) then
- var path = new Path[N](cost)
+ var path = new AStarPath[N](cost)
while frontier_node != self do
path.nodes.unshift(frontier_node)
- frontier_node = frontier_node.best_source.as(not null)
+ frontier_node = frontier_node.best_source
+ assert frontier_node != null
end
return path
# Link between two nodes and associated to a graph
class Link
+ # Type of the nodes in `graph`
type N: Node
+
+ # Type of the other links in `graph`
type L: Link
+ # The graph to which belongs `self`
var graph: Graph[N, L]
+ # Origin of this link
var from: N
+
+ # Endpoint of this link
var to: N
init
# General graph
class Graph[N: Node, L: Link]
+ # Nodes in this graph
var nodes: Set[N] = new HashSet[N]
+
+ # Links in this graph
var links: Set[L] = new HashSet[L]
+ # Add a `node` to this graph
fun add_node(node: N): N
do
nodes.add(node)
return node
end
+ # Add a `link` to this graph
fun add_link(link: L): L
do
links.add(link)
return link
end
- # used to check if nodes have been searched in one pathfinding
- var pathfinding_current_evocation: Int = 0
+ # Used to check if nodes have been searched in one pathfinding
+ private var pathfinding_current_evocation: Int = 0
end
-# Result from pathfinding, a walkable path
-class Path[N]
+# Result from path finding and a walkable path
+class AStarPath[N]
+ # The total cost of this path
var total_cost: Int
+ # The list of nodes composing this path
var nodes = new List[N]
+ private var at: Int = 0
- var at: Int = 0
+ # Step on the path and get the next node to travel
fun step: N
do
- assert nodes.length >= at else print "a_star::Path::step failed, is at_end_of_path"
+ assert nodes.length >= at else print "a_star::AStarPath::step failed, is at_end_of_path"
var s = nodes[at]
at += 1
return s
end
+ # Peek at the next step of the path
fun peek_step: N do return nodes[at]
+ # Are we at the end of this path?
fun at_end_of_path: Bool do return at >= nodes.length
end
# Context related to an evocation of pathfinding
class PathContext
+ # Type of the nodes in `graph`
type N: Node
+
+ # Type of the links in `graph`
type L: Link
+ # Graph to which is associated `self`
var graph: Graph[N, L]
# Worst cost of all the link's costs
# Heuristic
fun heuristic_cost(a, b: N): Int is abstract
+ # The worst cost suggested by the heuristic
fun worst_heuristic_cost: Int is abstract
end
redef fun worst_heuristic_cost do return 0
end
+# A `PathContext` for graphs with `WeightedLink`
class WeightedPathContext
super PathContext
redef fun worst_heuristic_cost do return 0
end
+# A `Link` with a `weight`
class WeightedLink
super Link
+ # The `weight`, or cost, of this link
var weight: Int
-
end
# Advanced path conditions with customizable accept states