Change initial pathfinding.
This commit is contained in:
parent
73c525985c
commit
f25b58448e
5 changed files with 254 additions and 186 deletions
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue