Rewrote path selection for conflict avoidance.

This commit is contained in:
hal8174 2024-02-17 02:42:38 +01:00
parent 8f6809c17f
commit 7fdf32342a
8 changed files with 514 additions and 439 deletions

View file

@ -1,12 +1,14 @@
use termcolor::{Color, ColorSpec};
use crate::belt_finding::{brute_force::BruteforceBuilder, common::Direction};
use crate::graph::wheighted_graph::shortest_path::dijkstra;
use crate::graph::wheighted_graph::WheightedGraph;
use crate::misc::Map;
use crate::priority_queue::BinaryHeap;
use colored::{Color, Colorize};
use std::fmt::Display;
use std::ops::{Deref, Index};
use self::common::{Position, PositionType};
use self::common::{print_map, Position, PositionType};
pub mod brute_force;
pub mod common;
@ -69,7 +71,11 @@ impl Problem {
for (i, path) in self.path.iter().enumerate() {
if i != without {
for p in path {
self.map.get_mut(p.x as usize, p.y as usize).wheight += 50.0;
let weight = 50.0;
let x = p.x as usize;
let y = p.y as usize;
self.map.get_mut(x, y).wheight += weight;
}
}
}
@ -84,89 +90,68 @@ impl Problem {
}
}
static COLORS: [Color; 12] = [
static COLORS: Cyclic<Color, 6> = Cyclic([
Color::Red,
Color::Green,
Color::Yellow,
Color::Blue,
Color::Magenta,
Color::Cyan,
Color::BrightRed,
Color::BrightGreen,
Color::BrightYellow,
Color::BrightBlue,
Color::BrightMagenta,
Color::Cyan,
];
]);
struct Cyclic<T, const N: usize>([T; N]);
impl<T, const N: usize> Index<usize> for Cyclic<T, N> {
type Output = T;
fn index(&self, index: usize) -> &Self::Output {
&self.0[index % N]
}
}
impl Display for Problem {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let width_digits = self.map.width.ilog10() + 1;
let height_digits = self.map.height.ilog10() + 1;
// print header
for i in 0..width_digits {
let d = width_digits - i - 1;
// padding
for _ in 0..height_digits {
write!(f, " ")?;
}
for x in 0..self.map.width {
let digits = x / (usize::pow(10, d));
if digits == 0 && d > 0 {
write!(f, " ")?;
} else {
write!(f, "{}", char::from_u32((digits % 10) as u32 + 48).unwrap())?;
}
}
writeln!(f)?;
}
// Print body
for y in 0..self.map.height {
write!(f, "{:1$}", y, height_digits as usize)?;
for x in 0..self.map.width {
if let Some(i) = self
.start
.iter()
print_map(self.map.width as i32, self.map.height as i32, |x, y| {
let mut color = ColorSpec::new();
if let Some(i) = self
.start
.iter()
.position(|p| p == &Position::new(x as PositionType, y as PositionType))
{
color.set_fg(Some(COLORS[i]));
(color, "s")
} else if let Some(i) = self
.end
.iter()
.position(|p| p == &Position::new(x as PositionType, y as PositionType))
{
color.set_fg(Some(COLORS[i]));
(color, "t")
} else if let Some((i, p)) = self.path.iter().enumerate().find_map(|(i, v)| {
v.iter()
.position(|p| p == &Position::new(x as PositionType, y as PositionType))
{
write!(f, "{}", "s".color(COLORS[i]))?;
} else if let Some(i) = self
.end
.iter()
.position(|p| p == &Position::new(x as PositionType, y as PositionType))
{
write!(f, "{}", "t".color(COLORS[i]))?;
} else if let Some((i, p)) = self.path.iter().enumerate().find_map(|(i, v)| {
v.iter()
.position(|p| p == &Position::new(x as PositionType, y as PositionType))
.map(|j| (i, j))
}) {
if self.path[i][p].x < self.path[i][p + 1].x {
write!(f, "{}", "".color(COLORS[i]))?;
} else if self.path[i][p].x > self.path[i][p + 1].x {
write!(f, "{}", "".color(COLORS[i]))?;
} else if self.path[i][p].y < self.path[i][p + 1].y {
write!(f, "{}", "".color(COLORS[i]))?;
} else if self.path[i][p].y > self.path[i][p + 1].y {
write!(f, "{}", "".color(COLORS[i]))?;
}
} else if self.map.get(x, y).blocked {
write!(f, "#")?;
} else if x % 8 == 0 || y % 8 == 0 {
write!(f, "")?;
.map(|j| (i, j))
}) {
color.set_fg(Some(COLORS[i]));
if self.path[i][p].x < self.path[i][p + 1].x {
(color, "")
} else if self.path[i][p].x > self.path[i][p + 1].x {
(color, "")
} else if self.path[i][p].y < self.path[i][p + 1].y {
(color, "")
} else if self.path[i][p].y > self.path[i][p + 1].y {
(color, "")
} else {
write!(f, " ")?;
unreachable!()
}
} else if self.map.get(x as usize, y as usize).blocked {
(color, "#")
} else if x % 8 == 0 || y % 8 == 0 {
(color, "")
} else {
(color, " ")
}
writeln!(f)?;
}
});
Ok(())
}
@ -339,4 +324,110 @@ pub mod problems {
p
}
pub fn belt_madness_level_5() -> Problem {
let mut p = Problem::new(31, 29);
// power stations
p.set_blocked_range(8, 8, 9, 9, true);
p.set_blocked_range(21, 8, 22, 9, true);
p.set_blocked_range(8, 19, 9, 20, true);
p.set_blocked_range(21, 19, 22, 20, true);
// solar panels
p.set_blocked_range(12, 11, 14, 13, true);
p.set_blocked_range(16, 11, 18, 13, true);
p.set_blocked_range(12, 15, 14, 17, true);
p.set_blocked_range(16, 15, 18, 17, true);
// Top
p.set_blocked_range(7, 0, 8, 2, true);
p.set_blocked(8, 3, true);
p.set_blocked(9, 4, true);
p.set_blocked_range(10, 5, 20, 5, true);
p.set_blocked(21, 4, true);
p.set_blocked(22, 3, true);
p.set_blocked_range(22, 0, 23, 2, true);
p.set_blocked_range(2, 1, 2, 2, true);
p.set_blocked_range(4, 1, 4, 2, true);
p.set_blocked_range(1, 4, 2, 4, true);
p.set_blocked_range(12, 1, 12, 2, true);
p.set_blocked_range(14, 1, 14, 2, true);
p.set_blocked_range(16, 1, 16, 2, true);
p.set_blocked_range(18, 1, 18, 2, true);
p.set_blocked_range(28, 4, 29, 4, true);
p.set_blocked_range(26, 1, 26, 2, true);
p.set_blocked_range(28, 1, 28, 2, true);
// Bottom
p.set_blocked_range(7, 26, 8, 28, true);
p.set_blocked(8, 25, true);
p.set_blocked(9, 24, true);
p.set_blocked_range(10, 23, 20, 23, true);
p.set_blocked(21, 24, true);
p.set_blocked(22, 25, true);
p.set_blocked_range(22, 26, 23, 28, true);
p.set_blocked_range(1, 26, 2, 26, true);
p.set_blocked_range(4, 26, 4, 27, true);
p.set_blocked_range(1, 24, 2, 24, true);
p.set_blocked_range(12, 26, 12, 27, true);
p.set_blocked_range(14, 26, 14, 27, true);
p.set_blocked_range(16, 26, 16, 27, true);
p.set_blocked_range(18, 26, 18, 27, true);
p.set_blocked_range(28, 24, 29, 24, true);
p.set_blocked_range(26, 26, 26, 27, true);
p.set_blocked_range(28, 26, 29, 26, true);
// Left
p.set_blocked_range(0, 7, 2, 8, true);
p.set_blocked(3, 8, true);
p.set_blocked(4, 9, true);
p.set_blocked_range(5, 10, 5, 18, true);
p.set_blocked(4, 19, true);
p.set_blocked(3, 20, true);
p.set_blocked_range(0, 20, 2, 21, true);
p.set_blocked_range(1, 11, 2, 11, true);
p.set_blocked_range(1, 13, 2, 13, true);
p.set_blocked_range(1, 15, 2, 15, true);
p.set_blocked_range(1, 17, 2, 17, true);
// Right
p.set_blocked_range(28, 7, 30, 8, true);
p.set_blocked(27, 8, true);
p.set_blocked(26, 9, true);
p.set_blocked_range(25, 10, 25, 18, true);
p.set_blocked(26, 19, true);
p.set_blocked(27, 20, true);
p.set_blocked_range(28, 20, 30, 21, true);
p.set_blocked_range(28, 11, 29, 11, true);
p.set_blocked_range(28, 13, 29, 13, true);
p.set_blocked_range(28, 15, 29, 15, true);
p.set_blocked_range(28, 17, 29, 17, true);
// Path
p.add_connection(Position::new(4, 3), Position::new(26, 25));
p.add_connection(Position::new(12, 3), Position::new(18, 25));
p.add_connection(Position::new(14, 3), Position::new(3, 26));
p.add_connection(Position::new(16, 3), Position::new(14, 25));
p.add_connection(Position::new(3, 4), Position::new(27, 24));
p.add_connection(Position::new(3, 11), Position::new(27, 17));
p.add_connection(Position::new(3, 13), Position::new(27, 26));
p.add_connection(Position::new(3, 15), Position::new(27, 13));
p.add_connection(Position::new(27, 15), Position::new(2, 3));
p.add_connection(Position::new(3, 17), Position::new(18, 3));
p.add_connection(Position::new(3, 24), Position::new(26, 3));
p.add_connection(Position::new(4, 25), Position::new(27, 4));
p.add_connection(Position::new(12, 25), Position::new(27, 11));
p.add_connection(Position::new(16, 25), Position::new(28, 3));
p
}
}