feat: improved path rendering
This commit is contained in:
parent
ddedf745f4
commit
6804359aff
|
@ -22,6 +22,8 @@ pub struct Graph {
|
|||
nodes: Slab<Node>,
|
||||
start: usize,
|
||||
end: usize,
|
||||
|
||||
maps: Vec<Vec<Vec<char>>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -42,7 +44,10 @@ pub enum Action {
|
|||
ChangeFloor(usize, usize),
|
||||
}
|
||||
|
||||
pub struct Actions(pub Vec<Action>);
|
||||
pub struct Actions {
|
||||
pub actions: Vec<Action>,
|
||||
pub maps: Vec<Vec<Vec<char>>>,
|
||||
}
|
||||
|
||||
#[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::<Vec<String>>()
|
||||
.join("\n"),
|
||||
layers[1]
|
||||
maps[1]
|
||||
.iter()
|
||||
.map(|chrs| String::from_iter(chrs))
|
||||
.collect::<Vec<String>>()
|
||||
|
@ -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(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(())
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue