feat: implemented path rendering
This commit is contained in:
parent
0f479302dd
commit
ddedf745f4
|
@ -1,5 +1,6 @@
|
|||
use anyhow::{Error, Result};
|
||||
use slab::Slab;
|
||||
use std::fmt::{Display, Formatter};
|
||||
use std::path::Path;
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -11,6 +12,9 @@ struct Edge {
|
|||
#[derive(Debug)]
|
||||
struct Node {
|
||||
edges: Slab<Edge>,
|
||||
x: usize,
|
||||
y: usize,
|
||||
z: usize,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -27,6 +31,19 @@ enum MapNode {
|
|||
Unknown(char),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Action {
|
||||
Start(usize, usize),
|
||||
End(usize, usize),
|
||||
Up(usize, usize),
|
||||
Down(usize, usize),
|
||||
Left(usize, usize),
|
||||
Right(usize, usize),
|
||||
ChangeFloor(usize, usize),
|
||||
}
|
||||
|
||||
pub struct Actions(pub Vec<Action>);
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct DijkstraNode {
|
||||
parent: usize,
|
||||
|
@ -40,8 +57,13 @@ impl Edge {
|
|||
}
|
||||
|
||||
impl Node {
|
||||
fn new() -> Self {
|
||||
Self { edges: Slab::new() }
|
||||
fn new(x: usize, y: usize, z: usize) -> Self {
|
||||
Self {
|
||||
edges: Slab::new(),
|
||||
x,
|
||||
y,
|
||||
z,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -54,6 +76,97 @@ 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() {
|
||||
match action {
|
||||
Action::Start(x, y) => {
|
||||
layers[z][y - y1][x - x1] = 'A';
|
||||
}
|
||||
Action::End(x, y) => {
|
||||
layers[z][y - y1][x - x1] = 'B';
|
||||
start = false;
|
||||
}
|
||||
Action::Up(x, y) => {
|
||||
layers[z][y - y1][x - x1] = '↑';
|
||||
start = false;
|
||||
}
|
||||
Action::Down(x, y) => {
|
||||
layers[z][y - y1][x - x1] = '↓';
|
||||
start = false;
|
||||
}
|
||||
Action::Left(x, y) => {
|
||||
layers[z][y - y1][x - x1] = '←';
|
||||
start = false;
|
||||
}
|
||||
Action::Right(x, y) => {
|
||||
layers[z][y - y1][x - x1] = '→';
|
||||
start = false;
|
||||
}
|
||||
Action::ChangeFloor(x, y) => {
|
||||
if !start {
|
||||
layers[z][y - y1][x - x1] = '!';
|
||||
}
|
||||
z = (z + 1) % 2;
|
||||
layers[z][y - y1][x - x1] = '!';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
write!(
|
||||
f,
|
||||
"Layer 0:\n{}\n\nLayer 1:\n{}",
|
||||
layers[0]
|
||||
.iter()
|
||||
.map(|chrs| String::from_iter(chrs))
|
||||
.collect::<Vec<String>>()
|
||||
.join("\n"),
|
||||
layers[1]
|
||||
.iter()
|
||||
.map(|chrs| String::from_iter(chrs))
|
||||
.collect::<Vec<String>>()
|
||||
.join("\n")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl Graph {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
|
@ -75,15 +188,18 @@ impl Graph {
|
|||
.unwrap()
|
||||
.1
|
||||
.split("\n\n")
|
||||
.map(|block| {
|
||||
.enumerate()
|
||||
.map(|(z, block)| {
|
||||
block
|
||||
.lines()
|
||||
.map(|line| {
|
||||
.enumerate()
|
||||
.map(|(y, line)| {
|
||||
line.chars()
|
||||
.map(|c| match c {
|
||||
.enumerate()
|
||||
.map(|(x, c)| match c {
|
||||
'#' => MapNode::Wall,
|
||||
'.' | 'A' | 'B' => {
|
||||
let id = graph.nodes.insert(Node::new());
|
||||
let id = graph.nodes.insert(Node::new(x, y, z));
|
||||
|
||||
if c == 'A' {
|
||||
graph.start = id;
|
||||
|
@ -104,16 +220,16 @@ impl Graph {
|
|||
|
||||
// connect nodes
|
||||
for (z, map) in maps.iter().enumerate() {
|
||||
print!("\n");
|
||||
// print!("\n");
|
||||
for (y, row) in map.iter().enumerate() {
|
||||
print!("\n");
|
||||
// print!("\n");
|
||||
for (x, map_node) in row.iter().enumerate() {
|
||||
match map_node {
|
||||
MapNode::Wall => print!("--- "),
|
||||
MapNode::Wall => continue, // print!("--- "),
|
||||
MapNode::Floor(id) => {
|
||||
let node = graph.nodes.get_mut(id.to_owned()).unwrap();
|
||||
|
||||
print!("{:03} ", id);
|
||||
// print!("{:03} ", id);
|
||||
|
||||
if let MapNode::Floor(i) = row[x - 1] {
|
||||
node.edges.insert(Edge::new(i, 1));
|
||||
|
@ -138,7 +254,7 @@ impl Graph {
|
|||
}
|
||||
}
|
||||
}
|
||||
print!("\n");
|
||||
// print!("\n");
|
||||
|
||||
Ok(graph)
|
||||
}
|
||||
|
@ -204,4 +320,46 @@ impl Graph {
|
|||
|
||||
Ok(path)
|
||||
}
|
||||
|
||||
pub fn path_to_actions(&self, path: &Vec<usize>) -> Result<Actions> {
|
||||
let start = self.nodes.get(self.start).unwrap();
|
||||
let mut x = start.x;
|
||||
let mut y = start.y;
|
||||
let mut z = start.z;
|
||||
let mut last_id = self.start;
|
||||
|
||||
let mut actions: Vec<Action> = path
|
||||
.iter()
|
||||
.map(|id| {
|
||||
let node = self.nodes.get(id.to_owned()).unwrap();
|
||||
|
||||
let action = {
|
||||
if id.to_owned() == self.start {
|
||||
Action::Start(node.x, node.y)
|
||||
} else if x > node.x {
|
||||
Action::Left(node.x, node.y)
|
||||
} else if x < node.x {
|
||||
Action::Right(node.x, node.y)
|
||||
} else if y > node.y {
|
||||
Action::Up(node.x, node.y)
|
||||
} else if y < node.y {
|
||||
Action::Down(node.x, node.y)
|
||||
} else {
|
||||
Action::ChangeFloor(node.x, node.y)
|
||||
}
|
||||
};
|
||||
|
||||
x = node.x;
|
||||
y = node.y;
|
||||
z = node.z;
|
||||
last_id = id.to_owned();
|
||||
|
||||
action
|
||||
})
|
||||
.collect();
|
||||
|
||||
actions.push(Action::End(x, y));
|
||||
|
||||
Ok(Actions(actions))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,8 @@ fn main() -> Result<()> {
|
|||
|
||||
let graph = Graph::new(Path::new(&args.file))?;
|
||||
let path = graph.dijkstra()?;
|
||||
println!("Path: {:?}", path);
|
||||
let actions = graph.path_to_actions(&path)?;
|
||||
println!("{}", actions);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue