From 6804359affd5f2ba9aaa2c90051348d6bed88543 Mon Sep 17 00:00:00 2001 From: antifallobst Date: Fri, 15 Sep 2023 00:04:28 +0200 Subject: [PATCH] feat: improved path rendering --- zauberschule/src/graph.rs | 120 +++++++++++++++++++++----------------- zauberschule/src/main.rs | 6 +- 2 files changed, 70 insertions(+), 56 deletions(-) diff --git a/zauberschule/src/graph.rs b/zauberschule/src/graph.rs index 39bc17e..c2f893d 100644 --- a/zauberschule/src/graph.rs +++ b/zauberschule/src/graph.rs @@ -22,6 +22,8 @@ pub struct Graph { nodes: Slab, start: usize, end: usize, + + maps: Vec>>, } #[derive(Debug)] @@ -42,7 +44,10 @@ pub enum Action { ChangeFloor(usize, usize), } -pub struct Actions(pub Vec); +pub struct Actions { + pub actions: Vec, + pub maps: Vec>>, +} #[derive(Debug, Clone)] struct DijkstraNode { @@ -78,74 +83,53 @@ impl DijkstraNode { impl Display for Actions { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - let mut x1 = usize::MAX; - let mut x2 = 0usize; - let mut y1 = usize::MAX; - let mut y2 = 0usize; - - for action in self.0.iter() { - match action { - Action::Start(x, y) - | Action::End(x, y) - | Action::Up(x, y) - | Action::Down(x, y) - | Action::Right(x, y) - | Action::Left(x, y) - | Action::ChangeFloor(x, y) => { - let x_pos = x.to_owned(); - let y_pos = y.to_owned(); - - if x_pos < x1 { - x1 = x_pos; - } - if x_pos > x2 { - x2 = x_pos; - } - if y_pos < y1 { - y1 = y_pos; - } - if y_pos > y2 { - y2 = y_pos; - } - } - } - } - - let mut layers = vec![vec![vec![' '; x2 - x1 + 1]; y2 - y1 + 1]; 2]; let mut z = 0usize; let mut start = true; - for action in self.0.iter() { + let mut maps = self.maps.to_owned(); + + for action in self.actions.iter() { match action { Action::Start(x, y) => { - layers[z][y - y1][x - x1] = 'A'; + maps[z][y.to_owned()][x.to_owned()] = 'A'; } Action::End(x, y) => { - layers[z][y - y1][x - x1] = 'B'; + maps[z][y.to_owned()][x.to_owned()] = 'B'; start = false; } Action::Up(x, y) => { - layers[z][y - y1][x - x1] = '↑'; + maps[z][y.to_owned()][x.to_owned()] = '↑'; start = false; } Action::Down(x, y) => { - layers[z][y - y1][x - x1] = '↓'; + maps[z][y.to_owned()][x.to_owned()] = '↓'; start = false; } Action::Left(x, y) => { - layers[z][y - y1][x - x1] = '←'; + maps[z][y.to_owned()][x.to_owned()] = '←'; start = false; } Action::Right(x, y) => { - layers[z][y - y1][x - x1] = '→'; + maps[z][y.to_owned()][x.to_owned()] = '→'; start = false; } Action::ChangeFloor(x, y) => { if !start { - layers[z][y - y1][x - x1] = '!'; + maps[z][y.to_owned()][x.to_owned()] = '!'; } z = (z + 1) % 2; - layers[z][y - y1][x - x1] = '!'; + maps[z][y.to_owned()][x.to_owned()] = '!'; + } + } + } + + for layer in maps.iter_mut() { + for line in layer { + for i in 1..(line.len() * 2) { + if (i % 2) == 0 { + continue; + } + line.insert(i, ' '); } } } @@ -153,12 +137,12 @@ impl Display for Actions { write!( f, "Layer 0:\n{}\n\nLayer 1:\n{}", - layers[0] + maps[0] .iter() .map(|chrs| String::from_iter(chrs)) .collect::>() .join("\n"), - layers[1] + maps[1] .iter() .map(|chrs| String::from_iter(chrs)) .collect::>() @@ -167,12 +151,29 @@ impl Display for Actions { } } +impl Actions { + pub fn seconds(&self) -> usize { + let mut seconds = 0usize; + + for action in self.actions.iter() { + seconds += match action { + Action::ChangeFloor(..) => 3, + Action::Start(..) | Action::End(..) => 0, + _ => 1, + }; + } + + seconds + } +} + impl Graph { fn default() -> Self { Self { nodes: Slab::new(), start: 0, end: 0, + maps: Vec::new(), } } @@ -181,36 +182,42 @@ impl Graph { let file_content = std::fs::read_to_string(path)?; - // Split the raw content into two vectors of vectors of MapNodes - // Each vector represents a map layer that's split into rows. - let maps = file_content + graph.maps = file_content .split_once('\n') .unwrap() .1 .split("\n\n") + .map(|block| block.lines().map(|str| str.chars().collect()).collect()) + .collect(); + + // Split the raw content into two vectors of vectors of MapNodes + // Each vector represents a map layer that's split into rows. + let maps = graph + .maps + .iter() .enumerate() .map(|(z, block)| { block - .lines() + .iter() .enumerate() .map(|(y, line)| { - line.chars() + line.iter() .enumerate() .map(|(x, c)| match c { '#' => MapNode::Wall, '.' | 'A' | 'B' => { let id = graph.nodes.insert(Node::new(x, y, z)); - if c == 'A' { + if c.to_owned() == 'A' { graph.start = id; } - if c == 'B' { + if c.to_owned() == 'B' { graph.end = id; } MapNode::Floor(id) } - c => MapNode::Unknown(c), + c => MapNode::Unknown(c.to_owned()), }) .collect() }) @@ -360,6 +367,9 @@ impl Graph { actions.push(Action::End(x, y)); - Ok(Actions(actions)) + Ok(Actions { + actions, + maps: self.maps.clone(), + }) } } diff --git a/zauberschule/src/main.rs b/zauberschule/src/main.rs index 3be2b18..f56d72a 100644 --- a/zauberschule/src/main.rs +++ b/zauberschule/src/main.rs @@ -22,7 +22,11 @@ fn main() -> Result<()> { let graph = Graph::new(Path::new(&args.file))?; let path = graph.dijkstra()?; let actions = graph.path_to_actions(&path)?; - println!("{}", actions); + println!("{}\n", actions); + println!( + "Ron needs {} seconds to travel from A to B.", + actions.seconds() + ); Ok(()) }