1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 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 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
use num::traits::Zero; use grid_2d::*; use direction::*; #[derive(Debug, Clone, Copy, Serialize, Deserialize)] pub struct DijkstraMapCell<Cost> { pub(crate) seen: u64, pub(crate) visited: u64, pub(crate) cost: Cost, pub(crate) direction: Direction, pub(crate) coord: Coord, } impl<Cost: Zero> DijkstraMapCell<Cost> { fn new(coord: Coord) -> Self { Self { seen: 0, visited: 0, cost: Zero::zero(), direction: Direction::North, coord, } } } impl<Cost> DijkstraMapCell<Cost> where Cost: Copy, { pub fn cost(&self) -> Cost { self.cost } pub fn direction(&self) -> Direction { self.direction } } #[derive(Debug, Clone)] pub enum DijkstraMapEntry<'a, Cost: 'a> { Origin, Unvisited, Outside, Cell(&'a DijkstraMapCell<Cost>), } impl<'a, Cost> DijkstraMapEntry<'a, Cost> { pub fn cell(self) -> Option<&'a DijkstraMapCell<Cost>> { match self { DijkstraMapEntry::Cell(c) => Some(c), _ => None, } } pub fn is_origin(self) -> bool { match self { DijkstraMapEntry::Origin => true, _ => false, } } pub fn is_unvisited(self) -> bool { match self { DijkstraMapEntry::Unvisited => true, _ => false, } } pub fn is_outside(self) -> bool { match self { DijkstraMapEntry::Outside => true, _ => false, } } } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct DijkstraMap<Cost> { pub(crate) seq: u64, pub(crate) grid: Grid<DijkstraMapCell<Cost>>, pub(crate) origin: Coord, } impl<Cost> DijkstraMap<Cost> where Cost: Zero + Copy, { pub fn new(width: u32, height: u32) -> Self { Self { seq: 1, grid: Grid::new_from_fn(width, height, DijkstraMapCell::new), origin: Coord::new(0, 0), } } pub fn get(&self, coord: Coord) -> DijkstraMapEntry<Cost> { if let Some(cell) = self.grid.get(coord) { if cell.seen == self.seq { if coord == self.origin { DijkstraMapEntry::Origin } else { DijkstraMapEntry::Cell(cell) } } else { DijkstraMapEntry::Unvisited } } else { DijkstraMapEntry::Outside } } }