basic_pathfinding/
node.rs1use std::cmp::Ordering;
2
3use crate::coord::Coord;
4use crate::search::Search;
5
6#[derive(Eq, Clone, Copy)]
7pub struct Node {
8 pub parent: Option<Coord>,
9 pub x: i32,
10 pub y: i32,
11 pub cost: i32,
12 pub distance: i32,
13 pub visited: bool,
14}
15
16impl Node {
17 pub fn new(parent: Option<&Node>, x: i32, y: i32, cost: i32, distance: i32) -> Node {
18 Node {
19 parent: match parent {
20 Some(parent) => Some(Coord::new(parent.x, parent.y)),
21 None => None,
22 },
23 x: x,
24 y: y,
25 cost: cost,
26 distance: distance,
27 visited: false,
28 }
29 }
30
31 pub fn guess_total_cost(&self) -> i32 {
32 self.cost + self.distance
33 }
34
35 pub fn format_path(&self, search: &Search) -> Vec<Coord> {
36 let mut nodes = vec![];
37 nodes.push(self);
38
39 let mut parent = &self.parent;
40 while parent.is_some() {
41 match parent {
42 None => (),
43 Some(p) => {
44 let node = search.get_node(p.x, p.y).unwrap();
45 parent = &node.parent;
46 nodes.push(node);
47 }
48 }
49 }
50
51 nodes.pop();
52 nodes.reverse();
53
54 let threshold = search.opts.cost_threshold;
55 let fully_path = threshold.is_some() & search.opts.path_to_threshold;
56 let threshold = match threshold {
57 None => 0,
58 Some(t) => t,
59 };
60
61 let mut path = vec![];
62 for node in nodes.iter() {
63 if !fully_path | (fully_path & (threshold >= node.cost)) {
64 path.push(Coord::new(node.x, node.y));
65 }
66 }
67
68 path.to_vec()
69 }
70}
71
72impl Ord for Node {
73 fn cmp(&self, other: &Self) -> Ordering {
74 match self.guess_total_cost().cmp(&other.guess_total_cost()) {
75 Ordering::Less => Ordering::Greater,
76 Ordering::Equal => Ordering::Equal,
77 Ordering::Greater => Ordering::Less,
78 }
79 }
80}
81
82impl PartialOrd for Node {
83 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
84 Some(self.cmp(other))
85 }
86}
87
88impl PartialEq for Node {
89 fn eq(&self, other: &Self) -> bool {
90 (self.x == other.x) & (self.y == other.y)
91 }
92}