Initial conflict avoidance.

This commit is contained in:
hal8174 2024-01-15 19:54:48 +01:00
parent 9751764611
commit 993fb0730c
4 changed files with 480 additions and 185 deletions

View file

@ -10,6 +10,7 @@ use self::common::Position;
pub mod brute_force;
pub mod common;
pub mod conflict_avoidance;
#[derive(Default, Clone, Copy)]
pub struct Field {
@ -216,137 +217,78 @@ impl Problem {
self.path[i] = p;
}
}
let mut conflicts: Map<usize> = Map::new(self.map.width, self.map.height);
for x in 0..self.map.width {
for y in 0..self.map.height {
if self.map.get(x, y).blocked {
*conflicts.get_mut(x, y) += 1;
}
}
}
for path in &self.path {
for pos in path {
*conflicts.get_mut(pos.x, pos.y) += 1;
}
}
for y in 0..self.map.height {
for x in 0..self.map.width {
if *conflicts.get(x, y) > 1 {
print!("#");
} else {
print!(" ");
}
}
println!();
}
println!("{self}");
loop {
let mut c = None;
for y in 0..self.map.height {
for x in 0..self.map.width {
if *conflicts.get(x, y) > 1 {
c = Some((x, y));
break;
}
}
}
dbg!(c);
let xoffset = 2;
let yoffset = 2;
if let Some((cx, cy)) = c {
*conflicts.get_mut(cx, cy) = 1;
let xrange = cx..=cx;
let yrange = cy..=cy;
let xrange = xrange.start().saturating_sub(xoffset)
..=usize::min(xrange.end() + xoffset, self.map.width - 1);
let yrange = yrange.start().saturating_sub(yoffset)
..=usize::min(yrange.end() + yoffset, self.map.height - 1);
// dbg!(&xrange, &yrange);
let xsize = xrange.end() - xrange.start() + 1;
let ysize = yrange.end() - yrange.start() + 1;
// dbg!(xsize, ysize);
let mut b = BruteforceBuilder::new(xsize + 2, ysize + 2);
b.set_blocked_range(0, 0, xsize + 1, 0, true);
b.set_blocked_range(0, ysize + 1, xsize + 1, ysize + 1, true);
b.set_blocked_range(0, 0, 0, ysize + 1, true);
b.set_blocked_range(xsize + 1, 0, xsize + 1, ysize + 1, true);
for x in 0..xsize {
for y in 0..ysize {
b.set_blocked(
x + 1,
y + 1,
self.map.get(xrange.start() + x, yrange.start() + y).blocked,
);
}
}
for path in &self.path {
let s = path
.iter()
.position(|p| xrange.contains(&p.x) && yrange.contains(&p.y))
.map(|i| i.saturating_sub(1));
let e = path
.iter()
.rev()
.position(|p| xrange.contains(&p.x) && yrange.contains(&p.y))
.map(|i| usize::min(path.len() - 1, path.len() - i));
if let Some((start, end)) = s.zip(e) {
// dbg!(start, end);
let start_pos = path[start];
let start_dir = Direction::from_neghbors(&path[start], &path[start + 1]);
let end_pos = path[end];
let end_dir = Direction::from_neghbors(&path[end - 1], &path[end]);
// dbg!(start_pos, end_pos);
b.add_path(
(
Position::new(
start_pos.x - (xrange.start() - 1),
start_pos.y - (yrange.start() - 1),
),
start_dir,
),
(
Position::new(
end_pos.x - (xrange.start() - 1),
end_pos.y - (yrange.start() - 1),
),
end_dir,
),
);
}
}
let mut b = b.build();
println!("{}", b);
while b.next_finish_state() {
println!("{}", b);
}
println!("{}", b.solution_count());
} else {
break;
}
}
}
}
pub mod problems {
use super::{common::Position, Problem};
pub fn belt_madness_level_1() -> Problem {
let mut p = Problem::new(17, 13);
p.set_blocked(0, 3, true);
p.set_blocked(1, 4, true);
p.set_blocked(2, 4, true);
p.set_blocked(1, 5, true);
p.set_blocked(2, 5, true);
p.set_blocked(1, 7, true);
p.set_blocked(2, 7, true);
p.set_blocked(1, 8, true);
p.set_blocked(2, 8, true);
p.set_blocked(0, 9, true);
p.set_blocked(16, 3, true);
p.set_blocked(14, 4, true);
p.set_blocked(15, 4, true);
p.set_blocked(14, 5, true);
p.set_blocked(15, 5, true);
p.set_blocked(14, 7, true);
p.set_blocked(15, 7, true);
p.set_blocked(14, 8, true);
p.set_blocked(15, 8, true);
p.set_blocked(16, 9, true);
p.add_connection(Position::new(3, 7), Position::new(13, 4));
p.add_connection(Position::new(3, 8), Position::new(13, 5));
p.add_connection(Position::new(3, 4), Position::new(13, 8));
p.add_connection(Position::new(3, 5), Position::new(13, 7));
p
}
pub fn belt_madness_level_2() -> Problem {
let mut p = Problem::new(33, 13);
p.set_blocked_range(1, 3, 2, 5, true);
p.set_blocked_range(1, 7, 2, 9, true);
p.set_blocked(0, 3, true);
p.set_blocked(0, 8, true);
p.set_blocked_range(10, 0, 21, 2, true);
p.set_blocked_range(10, 5, 21, 7, true);
p.set_blocked_range(10, 10, 21, 12, true);
p.set_blocked_range(30, 3, 31, 5, true);
p.set_blocked_range(30, 7, 31, 9, true);
p.set_blocked(32, 3, true);
p.set_blocked(32, 9, true);
p.add_connection(Position::new(3, 3), Position::new(29, 7));
p.add_connection(Position::new(3, 4), Position::new(29, 9));
p.add_connection(Position::new(3, 5), Position::new(29, 8));
p.add_connection(Position::new(3, 7), Position::new(29, 3));
p.add_connection(Position::new(3, 8), Position::new(29, 5));
p.add_connection(Position::new(3, 9), Position::new(29, 4));
p
}
}