feat: implemented path rendering
This commit is contained in:
parent
0f479302dd
commit
ddedf745f4
|
@ -1,5 +1,6 @@
|
||||||
use anyhow::{Error, Result};
|
use anyhow::{Error, Result};
|
||||||
use slab::Slab;
|
use slab::Slab;
|
||||||
|
use std::fmt::{Display, Formatter};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -11,6 +12,9 @@ struct Edge {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Node {
|
struct Node {
|
||||||
edges: Slab<Edge>,
|
edges: Slab<Edge>,
|
||||||
|
x: usize,
|
||||||
|
y: usize,
|
||||||
|
z: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -27,6 +31,19 @@ enum MapNode {
|
||||||
Unknown(char),
|
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)]
|
#[derive(Debug, Clone)]
|
||||||
struct DijkstraNode {
|
struct DijkstraNode {
|
||||||
parent: usize,
|
parent: usize,
|
||||||
|
@ -40,8 +57,13 @@ impl Edge {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Node {
|
impl Node {
|
||||||
fn new() -> Self {
|
fn new(x: usize, y: usize, z: usize) -> Self {
|
||||||
Self { edges: Slab::new() }
|
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 {
|
impl Graph {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
@ -75,15 +188,18 @@ impl Graph {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.1
|
.1
|
||||||
.split("\n\n")
|
.split("\n\n")
|
||||||
.map(|block| {
|
.enumerate()
|
||||||
|
.map(|(z, block)| {
|
||||||
block
|
block
|
||||||
.lines()
|
.lines()
|
||||||
.map(|line| {
|
.enumerate()
|
||||||
|
.map(|(y, line)| {
|
||||||
line.chars()
|
line.chars()
|
||||||
.map(|c| match c {
|
.enumerate()
|
||||||
|
.map(|(x, c)| match c {
|
||||||
'#' => MapNode::Wall,
|
'#' => MapNode::Wall,
|
||||||
'.' | 'A' | 'B' => {
|
'.' | 'A' | 'B' => {
|
||||||
let id = graph.nodes.insert(Node::new());
|
let id = graph.nodes.insert(Node::new(x, y, z));
|
||||||
|
|
||||||
if c == 'A' {
|
if c == 'A' {
|
||||||
graph.start = id;
|
graph.start = id;
|
||||||
|
@ -104,16 +220,16 @@ impl Graph {
|
||||||
|
|
||||||
// connect nodes
|
// connect nodes
|
||||||
for (z, map) in maps.iter().enumerate() {
|
for (z, map) in maps.iter().enumerate() {
|
||||||
print!("\n");
|
// print!("\n");
|
||||||
for (y, row) in map.iter().enumerate() {
|
for (y, row) in map.iter().enumerate() {
|
||||||
print!("\n");
|
// print!("\n");
|
||||||
for (x, map_node) in row.iter().enumerate() {
|
for (x, map_node) in row.iter().enumerate() {
|
||||||
match map_node {
|
match map_node {
|
||||||
MapNode::Wall => print!("--- "),
|
MapNode::Wall => continue, // print!("--- "),
|
||||||
MapNode::Floor(id) => {
|
MapNode::Floor(id) => {
|
||||||
let node = graph.nodes.get_mut(id.to_owned()).unwrap();
|
let node = graph.nodes.get_mut(id.to_owned()).unwrap();
|
||||||
|
|
||||||
print!("{:03} ", id);
|
// print!("{:03} ", id);
|
||||||
|
|
||||||
if let MapNode::Floor(i) = row[x - 1] {
|
if let MapNode::Floor(i) = row[x - 1] {
|
||||||
node.edges.insert(Edge::new(i, 1));
|
node.edges.insert(Edge::new(i, 1));
|
||||||
|
@ -138,7 +254,7 @@ impl Graph {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
print!("\n");
|
// print!("\n");
|
||||||
|
|
||||||
Ok(graph)
|
Ok(graph)
|
||||||
}
|
}
|
||||||
|
@ -204,4 +320,46 @@ impl Graph {
|
||||||
|
|
||||||
Ok(path)
|
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 graph = Graph::new(Path::new(&args.file))?;
|
||||||
let path = graph.dijkstra()?;
|
let path = graph.dijkstra()?;
|
||||||
println!("Path: {:?}", path);
|
let actions = graph.path_to_actions(&path)?;
|
||||||
|
println!("{}", actions);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue