feat: improved path rendering
This commit is contained in:
parent
ddedf745f4
commit
6804359aff
|
@ -22,6 +22,8 @@ pub struct Graph {
|
||||||
nodes: Slab<Node>,
|
nodes: Slab<Node>,
|
||||||
start: usize,
|
start: usize,
|
||||||
end: usize,
|
end: usize,
|
||||||
|
|
||||||
|
maps: Vec<Vec<Vec<char>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -42,7 +44,10 @@ pub enum Action {
|
||||||
ChangeFloor(usize, usize),
|
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)]
|
#[derive(Debug, Clone)]
|
||||||
struct DijkstraNode {
|
struct DijkstraNode {
|
||||||
|
@ -78,74 +83,53 @@ impl DijkstraNode {
|
||||||
|
|
||||||
impl Display for Actions {
|
impl Display for Actions {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
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 z = 0usize;
|
||||||
let mut start = true;
|
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 {
|
match action {
|
||||||
Action::Start(x, y) => {
|
Action::Start(x, y) => {
|
||||||
layers[z][y - y1][x - x1] = 'A';
|
maps[z][y.to_owned()][x.to_owned()] = 'A';
|
||||||
}
|
}
|
||||||
Action::End(x, y) => {
|
Action::End(x, y) => {
|
||||||
layers[z][y - y1][x - x1] = 'B';
|
maps[z][y.to_owned()][x.to_owned()] = 'B';
|
||||||
start = false;
|
start = false;
|
||||||
}
|
}
|
||||||
Action::Up(x, y) => {
|
Action::Up(x, y) => {
|
||||||
layers[z][y - y1][x - x1] = '↑';
|
maps[z][y.to_owned()][x.to_owned()] = '↑';
|
||||||
start = false;
|
start = false;
|
||||||
}
|
}
|
||||||
Action::Down(x, y) => {
|
Action::Down(x, y) => {
|
||||||
layers[z][y - y1][x - x1] = '↓';
|
maps[z][y.to_owned()][x.to_owned()] = '↓';
|
||||||
start = false;
|
start = false;
|
||||||
}
|
}
|
||||||
Action::Left(x, y) => {
|
Action::Left(x, y) => {
|
||||||
layers[z][y - y1][x - x1] = '←';
|
maps[z][y.to_owned()][x.to_owned()] = '←';
|
||||||
start = false;
|
start = false;
|
||||||
}
|
}
|
||||||
Action::Right(x, y) => {
|
Action::Right(x, y) => {
|
||||||
layers[z][y - y1][x - x1] = '→';
|
maps[z][y.to_owned()][x.to_owned()] = '→';
|
||||||
start = false;
|
start = false;
|
||||||
}
|
}
|
||||||
Action::ChangeFloor(x, y) => {
|
Action::ChangeFloor(x, y) => {
|
||||||
if !start {
|
if !start {
|
||||||
layers[z][y - y1][x - x1] = '!';
|
maps[z][y.to_owned()][x.to_owned()] = '!';
|
||||||
}
|
}
|
||||||
z = (z + 1) % 2;
|
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!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"Layer 0:\n{}\n\nLayer 1:\n{}",
|
"Layer 0:\n{}\n\nLayer 1:\n{}",
|
||||||
layers[0]
|
maps[0]
|
||||||
.iter()
|
.iter()
|
||||||
.map(|chrs| String::from_iter(chrs))
|
.map(|chrs| String::from_iter(chrs))
|
||||||
.collect::<Vec<String>>()
|
.collect::<Vec<String>>()
|
||||||
.join("\n"),
|
.join("\n"),
|
||||||
layers[1]
|
maps[1]
|
||||||
.iter()
|
.iter()
|
||||||
.map(|chrs| String::from_iter(chrs))
|
.map(|chrs| String::from_iter(chrs))
|
||||||
.collect::<Vec<String>>()
|
.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 {
|
impl Graph {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
nodes: Slab::new(),
|
nodes: Slab::new(),
|
||||||
start: 0,
|
start: 0,
|
||||||
end: 0,
|
end: 0,
|
||||||
|
maps: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,36 +182,42 @@ impl Graph {
|
||||||
|
|
||||||
let file_content = std::fs::read_to_string(path)?;
|
let file_content = std::fs::read_to_string(path)?;
|
||||||
|
|
||||||
// Split the raw content into two vectors of vectors of MapNodes
|
graph.maps = file_content
|
||||||
// Each vector represents a map layer that's split into rows.
|
|
||||||
let maps = file_content
|
|
||||||
.split_once('\n')
|
.split_once('\n')
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.1
|
.1
|
||||||
.split("\n\n")
|
.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()
|
.enumerate()
|
||||||
.map(|(z, block)| {
|
.map(|(z, block)| {
|
||||||
block
|
block
|
||||||
.lines()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(y, line)| {
|
.map(|(y, line)| {
|
||||||
line.chars()
|
line.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(x, c)| match c {
|
.map(|(x, c)| match c {
|
||||||
'#' => MapNode::Wall,
|
'#' => MapNode::Wall,
|
||||||
'.' | 'A' | 'B' => {
|
'.' | 'A' | 'B' => {
|
||||||
let id = graph.nodes.insert(Node::new(x, y, z));
|
let id = graph.nodes.insert(Node::new(x, y, z));
|
||||||
|
|
||||||
if c == 'A' {
|
if c.to_owned() == 'A' {
|
||||||
graph.start = id;
|
graph.start = id;
|
||||||
}
|
}
|
||||||
if c == 'B' {
|
if c.to_owned() == 'B' {
|
||||||
graph.end = id;
|
graph.end = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
MapNode::Floor(id)
|
MapNode::Floor(id)
|
||||||
}
|
}
|
||||||
c => MapNode::Unknown(c),
|
c => MapNode::Unknown(c.to_owned()),
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
})
|
})
|
||||||
|
@ -360,6 +367,9 @@ impl Graph {
|
||||||
|
|
||||||
actions.push(Action::End(x, y));
|
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 graph = Graph::new(Path::new(&args.file))?;
|
||||||
let path = graph.dijkstra()?;
|
let path = graph.dijkstra()?;
|
||||||
let actions = graph.path_to_actions(&path)?;
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue