feat: improved path rendering

This commit is contained in:
antifallobst 2023-09-15 00:04:28 +02:00
parent ddedf745f4
commit 6804359aff
Signed by: antifallobst
GPG Key ID: 2B4F402172791BAF
2 changed files with 70 additions and 56 deletions

View File

@ -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(),
})
}
}

View File

@ -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(())
}