screeps_pathfinding/utils/
goals.rs

1use crate::common::traits::GetRangeTo;
2
3/// Helper function to create a goal function closure for exact node matching with a single goal node.
4///
5/// If using the convenience functions for common pathfinding use-cases,
6/// you will not normally need to use this function.
7///
8/// # Examples
9/// ```rust
10/// use screeps::RoomXY;
11/// use screeps_pathfinding::utils::goals::goal_exact_node;
12/// use screeps_pathfinding::utils::heuristics::heuristic_get_range_to;
13///
14/// let start = RoomXY::checked_new(24, 18).unwrap();
15/// let goal = RoomXY::checked_new(34, 40).unwrap();
16/// let cost_fn = |_| Some(1);
17/// screeps_pathfinding::algorithms::astar::shortest_path_roomxy(
18///     start,
19///     &goal_exact_node(goal),
20///     cost_fn,
21///     &heuristic_get_range_to(goal),
22/// );
23pub fn goal_exact_node<T: std::cmp::PartialEq + 'static>(goal: T) -> impl Fn(T) -> bool {
24    move |node: T| node == goal
25}
26
27/// Helper function to create a goal function closure for exact node matching with multiple goal nodes.
28///
29/// If using the convenience functions for common pathfinding use-cases,
30/// you will not normally need to use this function.
31///
32/// # Examples
33/// ```rust
34/// use screeps::RoomXY;
35/// use screeps_pathfinding::utils::goals::goal_exact_node_multigoal;
36/// use screeps_pathfinding::utils::heuristics::heuristic_get_range_to_multigoal;
37///
38/// let start = RoomXY::checked_new(24, 18).unwrap();
39/// let goal_a = RoomXY::checked_new(34, 40).unwrap();
40/// let goal_b = RoomXY::checked_new(34, 45).unwrap();
41/// let goals = &[goal_a, goal_b];
42/// let cost_fn = |_| Some(1);
43/// screeps_pathfinding::algorithms::astar::shortest_path_roomxy(
44///     start,
45///     &goal_exact_node_multigoal(goals),
46///     cost_fn,
47///     &heuristic_get_range_to_multigoal(goals),
48/// );
49pub fn goal_exact_node_multigoal<T: std::cmp::PartialEq>(goals: &[T]) -> impl Fn(T) -> bool + '_ {
50    |node: T| goals.contains(&node)
51}
52
53/// Helper function to create a goal function closure for matching
54/// nodes <= than the specified range from a single goal node.
55///
56/// If using the convenience functions for common pathfinding use-cases,
57/// you will not normally need to use this function.
58///
59/// # Examples
60/// ```rust
61/// use screeps::RoomXY;
62/// use screeps_pathfinding::utils::goals::goal_range_to_node;
63/// use screeps_pathfinding::utils::heuristics::heuristic_get_range_to;
64///
65/// let start = RoomXY::checked_new(24, 18).unwrap();
66/// let goal = RoomXY::checked_new(34, 40).unwrap();
67/// let cost_fn = |_| Some(1);
68/// screeps_pathfinding::algorithms::astar::shortest_path_roomxy(
69///     start,
70///     &goal_range_to_node(goal, 3),
71///     cost_fn,
72///     &heuristic_get_range_to(goal),
73/// );
74pub fn goal_range_to_node<T: GetRangeTo + Copy + 'static>(
75    goal: T,
76    range: u32,
77) -> impl Fn(T) -> bool {
78    move |node: T| node.get_range_to(goal) <= range
79}
80
81/// Helper function to create a goal function closure for matching
82/// nodes <= than the specified range from any of multiple goal nodes.
83///
84/// If using the convenience functions for common pathfinding use-cases,
85/// you will not normally need to use this function.
86///
87/// # Examples
88/// ```rust
89/// use screeps::RoomXY;
90/// use screeps_pathfinding::utils::goals::goal_range_to_node_multigoal;
91/// use screeps_pathfinding::utils::heuristics::heuristic_get_range_to_multigoal;
92///
93/// let start = RoomXY::checked_new(24, 18).unwrap();
94/// let goal_a = RoomXY::checked_new(34, 40).unwrap();
95/// let goal_b = RoomXY::checked_new(34, 45).unwrap();
96/// let goals = &[goal_a, goal_b];
97/// let cost_fn = |_| Some(1);
98/// screeps_pathfinding::algorithms::astar::shortest_path_roomxy(
99///     start,
100///     &goal_range_to_node_multigoal(goals, 3),
101///     cost_fn,
102///     &heuristic_get_range_to_multigoal(goals),
103/// );
104pub fn goal_range_to_node_multigoal<T: GetRangeTo + Copy>(
105    goals: &[T],
106    range: u32,
107) -> impl Fn(T) -> bool + '_ {
108    move |node: T| goals.iter().any(|g| node.get_range_to(*g) <= range)
109}