basic-pathfinding 0.2.8

Tile-based A* pathfinding in Rust
Documentation
use std::cmp::Ordering;

use crate::coord::Coord;
use crate::search::Search;

#[derive(Eq, Clone, Copy)]
pub struct Node {
  pub parent: Option<Coord>,
  pub x: i32,
  pub y: i32,
  pub cost: i32,
  pub distance: i32,
  pub visited: bool,
}

impl Node {
  pub fn new(parent: Option<&Node>, x: i32, y: i32, cost: i32, distance: i32) -> Node {
    Node {
      parent: match parent {
        Some(parent) => Some(Coord::new(parent.x, parent.y)),
        None => None,
      },
      x: x,
      y: y,
      cost: cost,
      distance: distance,
      visited: false,
    }
  }

  pub fn guess_total_cost(&self) -> i32 {
    self.cost + self.distance
  }

  pub fn format_path(&self, search: &Search) -> Vec<Coord> {
    let mut nodes = vec![];
    nodes.push(self);

    let mut parent = &self.parent;
    while parent.is_some() {
      match parent {
        None => (),
        Some(p) => {
          let node = search.get_node(p.x, p.y).unwrap();
          parent = &node.parent;
          nodes.push(node);
        }
      }
    }

    nodes.pop();
    nodes.reverse();

    let threshold = search.opts.cost_threshold;
    let fully_path = threshold.is_some() & search.opts.path_to_threshold;
    let threshold = match threshold {
      None => 0,
      Some(t) => t,
    };

    let mut path = vec![];
    for node in nodes.iter() {
      if !fully_path | (fully_path & (threshold >= node.cost)) {
        path.push(Coord::new(node.x, node.y));
      }
    }

    path.to_vec()
  }
}

impl Ord for Node {
  fn cmp(&self, other: &Self) -> Ordering {
    match self.guess_total_cost().cmp(&other.guess_total_cost()) {
      Ordering::Less => Ordering::Greater,
      Ordering::Equal => Ordering::Equal,
      Ordering::Greater => Ordering::Less,
    }
  }
}

impl PartialOrd for Node {
  fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
    Some(self.cmp(other))
  }
}

impl PartialEq for Node {
  fn eq(&self, other: &Self) -> bool {
    (self.x == other.x) & (self.y == other.y)
  }
}