Change initial pathfinding.

This commit is contained in:
hal8174 2024-03-20 23:11:21 +01:00
parent 73c525985c
commit f25b58448e
5 changed files with 254 additions and 186 deletions

View file

@ -23,7 +23,7 @@ pub struct Problem {
map: Map<Field>,
start: Vec<(Position, Direction)>,
end: Vec<(Position, Direction)>,
path: Vec<Vec<Position>>,
path: Vec<Vec<(Position, Direction)>>,
}
impl Problem {
@ -55,37 +55,37 @@ impl Problem {
}
fn calculate_wheights(&mut self, without: usize) {
for x in 0..self.map.width {
for y in 0..self.map.height {
let mut wheight = 1.0;
// for x in 0..self.map.width {
// for y in 0..self.map.height {
// let mut wheight = 1.0;
if self.map.get(x, y).blocked {
wheight += 100.0;
}
// if self.map.get(x, y).blocked {
// wheight += 100.0;
// }
self.map.get_mut(x, y).wheight = wheight;
}
}
// self.map.get_mut(x, y).wheight = wheight;
// }
// }
for (i, path) in self.path.iter().enumerate() {
if i != without {
for p in path {
let weight = 50.0;
let x = p.x as usize;
let y = p.y as usize;
// for (i, path) in self.path.iter().enumerate() {
// if i != without {
// for p in path {
// let weight = 50.0;
// let x = p.x as usize;
// let y = p.y as usize;
self.map.get_mut(x, y).wheight += weight;
}
}
}
// self.map.get_mut(x, y).wheight += weight;
// }
// }
// }
for p in &self.start {
self.map.get_mut(p.0.x as usize, p.0.y as usize).wheight = f64::INFINITY;
}
// for p in &self.start {
// self.map.get_mut(p.0.x as usize, p.0.y as usize).wheight = f64::INFINITY;
// }
for p in &self.end {
self.map.get_mut(p.0.x as usize, p.0.y as usize).wheight = f64::INFINITY;
}
// for p in &self.end {
// self.map.get_mut(p.0.x as usize, p.0.y as usize).wheight = f64::INFINITY;
// }
}
pub fn print(&self) {
@ -107,22 +107,16 @@ impl Problem {
(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))
.position(|p| p.0 == Position::new(x as PositionType, y as PositionType))
.map(|j| (i, j))
}) {
color.set_fg(Some(COLORS[i]));
let c = &self.path[i][p];
let n = self.path[i].get(p + 1).unwrap_or(&self.end[i].0);
if c.x < n.x {
(color, "")
} else if c.x > n.x {
(color, "")
} else if c.y < n.y {
(color, "")
} else if c.y > n.y {
(color, "")
} else {
unreachable!()
match c.1 {
Direction::Up => (color, ""),
Direction::Right => (color, ""),
Direction::Down => (color, ""),
Direction::Left => (color, ""),
}
} else if self.map.get(x as usize, y as usize).blocked {
(color, "#")
@ -156,54 +150,102 @@ impl<T, const N: usize> Index<usize> for Cyclic<T, N> {
struct MapInternal<'a> {
map: &'a Map<Field>,
}
impl<'a> MapInternal<'a> {
fn get_direction(&self, pos: Position) -> [Option<Position>; 4] {
let min = Position::new(0, 0);
let max = Position::new(
self.map.width as PositionType,
self.map.height as PositionType,
);
[
Position::new(pos.x - 1, pos.y)
.in_range(&min, &max)
.copied(),
Position::new(pos.x + 1, pos.y)
.in_range(&min, &max)
.copied(),
Position::new(pos.x, pos.y - 1)
.in_range(&min, &max)
.copied(),
Position::new(pos.x, pos.y + 1)
.in_range(&min, &max)
.copied(),
]
}
end: (Position, Direction),
}
impl<'a> WheightedGraph for MapInternal<'a> {
type Node = Position;
type Node = (Position, Direction);
fn num_edges(&self, node: &Self::Node) -> usize {
if self.map.get(node.x as usize, node.y as usize).blocked {
0
} else {
let t = self.get_direction(*node);
todo!();
// let next = node.0.in_direction(&node.1, 1);
// if next
// .in_range(
// &Position::new(0, 0),
// &Position::new(
// self.map.width as PositionType,
// self.map.height as PositionType,
// ),
// )
// .is_some()
// {
// return 0;
// }
let v = t.iter().flatten();
// if self.map.get(next.x as usize, next.y as usize).blocked {
// return 0;
// }
v.count()
}
// let mut count = 3;
// for l in 2..=6 {
// let n = node.0.in_direction(&node.1, l);
// dbg!(n, l);
// if n.in_range(
// &Position::new(0, 0),
// &Position::new(
// self.map.width as PositionType,
// self.map.height as PositionType,
// ),
// )
// .is_some()
// {
// return count;
// }
// if !self.map.get(n.x as usize, n.y as usize).blocked {
// count += 1;
// }
// }
// count
}
fn edge(&self, node: &Self::Node, num: usize) -> Option<(Self::Node, f64)> {
let t = self.get_direction(*node);
t.iter()
.flatten()
.nth(num)
.map(|&p| (p, self.map.get(p.x as usize, p.y as usize).wheight))
let next = node.0.in_direction(&node.1, 1);
if next
.in_range(
&Position::new(0, 0),
&Position::new(
self.map.width as PositionType,
self.map.height as PositionType,
),
)
.is_none()
{
return None;
}
if self.map.get(next.x as usize, next.y as usize).blocked && self.end != (next, node.1) {
return None;
}
match num {
0 => Some(((next, node.1), 1.5)),
1 => Some(((next, node.1.counter_clockwise()), 1.5)),
2 => Some(((next, node.1.clockwise()), 1.5)),
_ => {
let mut count = 2;
for l in 2..=6 {
let n = node.0.in_direction(&node.1, l);
if n.in_range(
&Position::new(0, 0),
&Position::new(
self.map.width as PositionType,
self.map.height as PositionType,
),
)
.is_none()
{
return None;
}
if !self.map.get(n.x as usize, n.y as usize).blocked {
count += 1;
if count == num {
return Some(((n, node.1), 17.5));
}
}
}
None
}
}
}
}
@ -211,13 +253,11 @@ impl Problem {
pub fn find_path(&mut self) {
for i in 0..self.start.len() {
self.calculate_wheights(i);
let m = MapInternal { map: &self.map };
let p = dijkstra::<MapInternal, FibonacciHeap<_>>(
&m,
self.start[i].0.in_direction(&self.start[i].1, 1),
self.end[i].0.in_direction(&self.end[i].1, -1),
);
let m = MapInternal {
map: &self.map,
end: self.end[i],
};
let p = dijkstra::<MapInternal, FibonacciHeap<_>>(&m, self.start[i], self.end[i]);
if let Some(p) = p {
self.path[i] = p;
}
@ -231,6 +271,19 @@ pub mod problems {
Problem,
};
pub fn simple() -> Problem {
let mut p = Problem::new(5, 3);
p.set_blocked_range(2, 0, 2, 2, true);
p.add_connection(
(Position::new(0, 1), Direction::Right),
(Position::new(4, 1), Direction::Right),
);
p
}
pub fn belt_madness_level_1() -> Problem {
let mut p = Problem::new(17, 13);
@ -264,20 +317,20 @@ pub mod problems {
p.add_connection(
(Position::new(2, 7), Direction::Right),
(Position::new(14, 4), Direction::Right),
(Position::new(13, 4), Direction::Right),
);
p.add_connection(
(Position::new(2, 8), Direction::Right),
(Position::new(14, 5), Direction::Right),
(Position::new(13, 5), Direction::Right),
);
p.add_connection(
(Position::new(2, 4), Direction::Right),
(Position::new(14, 8), Direction::Right),
(Position::new(13, 8), Direction::Right),
);
p.add_connection(
(Position::new(2, 5), Direction::Right),
(Position::new(14, 7), Direction::Right),
(Position::new(13, 7), Direction::Right),
);
p
@ -301,36 +354,36 @@ pub mod problems {
p.add_connection(
(Position::new(2, 4), Direction::Right),
(Position::new(14, 2), Direction::Right),
(Position::new(13, 2), Direction::Right),
);
p.add_connection(
(Position::new(2, 7), Direction::Right),
(Position::new(14, 3), Direction::Right),
(Position::new(13, 3), Direction::Right),
);
p.add_connection(
(Position::new(2, 10), Direction::Right),
(Position::new(14, 4), Direction::Right),
(Position::new(13, 4), Direction::Right),
);
p.add_connection(
(Position::new(2, 9), Direction::Right),
(Position::new(14, 5), Direction::Right),
(Position::new(13, 5), Direction::Right),
);
p.add_connection(
(Position::new(2, 2), Direction::Right),
(Position::new(14, 7), Direction::Right),
(Position::new(13, 7), Direction::Right),
);
p.add_connection(
(Position::new(2, 3), Direction::Right),
(Position::new(14, 8), Direction::Right),
(Position::new(13, 8), Direction::Right),
);
p.add_connection(
(Position::new(2, 5), Direction::Right),
(Position::new(14, 9), Direction::Right),
(Position::new(13, 9), Direction::Right),
);
p.add_connection(
(Position::new(2, 8), Direction::Right),
(Position::new(14, 10), Direction::Right),
(Position::new(13, 10), Direction::Right),
);
p
@ -473,59 +526,59 @@ pub mod problems {
// Path
p.add_connection(
(Position::new(4, 2), Direction::Down),
(Position::new(26, 26), Direction::Down),
(Position::new(26, 25), Direction::Down),
);
p.add_connection(
(Position::new(12, 2), Direction::Down),
(Position::new(18, 26), Direction::Down),
(Position::new(18, 25), Direction::Down),
);
p.add_connection(
(Position::new(14, 2), Direction::Down),
(Position::new(2, 26), Direction::Left),
(Position::new(3, 26), Direction::Left),
);
p.add_connection(
(Position::new(16, 2), Direction::Down),
(Position::new(14, 26), Direction::Down),
(Position::new(14, 25), Direction::Down),
);
p.add_connection(
(Position::new(2, 4), Direction::Right),
(Position::new(28, 24), Direction::Right),
(Position::new(27, 24), Direction::Right),
);
p.add_connection(
(Position::new(2, 11), Direction::Right),
(Position::new(28, 17), Direction::Right),
(Position::new(27, 17), Direction::Right),
);
p.add_connection(
(Position::new(2, 13), Direction::Right),
(Position::new(28, 26), Direction::Right),
(Position::new(27, 26), Direction::Right),
);
p.add_connection(
(Position::new(2, 15), Direction::Right),
(Position::new(28, 13), Direction::Right),
(Position::new(27, 13), Direction::Right),
);
p.add_connection(
(Position::new(28, 15), Direction::Left),
(Position::new(2, 2), Direction::Up),
(Position::new(2, 3), Direction::Up),
);
p.add_connection(
(Position::new(2, 17), Direction::Right),
(Position::new(18, 2), Direction::Up),
(Position::new(18, 3), Direction::Up),
);
p.add_connection(
(Position::new(2, 24), Direction::Right),
(Position::new(26, 2), Direction::Up),
(Position::new(26, 3), Direction::Up),
);
p.add_connection(
(Position::new(4, 26), Direction::Up),
(Position::new(28, 4), Direction::Right),
(Position::new(27, 4), Direction::Right),
);
p.add_connection(
(Position::new(12, 26), Direction::Up),
(Position::new(28, 11), Direction::Right),
(Position::new(27, 11), Direction::Right),
);
p.add_connection(
(Position::new(16, 26), Direction::Up),
(Position::new(28, 2), Direction::Up),
(Position::new(28, 3), Direction::Up),
);
p