Simple complete conflict avoidance.

This commit is contained in:
hal8174 2024-01-16 02:31:20 +01:00
parent 993fb0730c
commit 2e9c699600
3 changed files with 83 additions and 18 deletions

View file

@ -1,3 +1,5 @@
use std::io;
use clap::{Parser, ValueEnum}; use clap::{Parser, ValueEnum};
use factorio_blueprint::belt_finding::{conflict_avoidance::ConflictAvoidance, problems, Problem}; use factorio_blueprint::belt_finding::{conflict_avoidance::ConflictAvoidance, problems, Problem};
@ -5,6 +7,7 @@ use factorio_blueprint::belt_finding::{conflict_avoidance::ConflictAvoidance, pr
enum Mode { enum Mode {
Solve, Solve,
ConflictAvoidance, ConflictAvoidance,
ConflictStep,
} }
#[derive(ValueEnum, Clone)] #[derive(ValueEnum, Clone)]
@ -51,5 +54,17 @@ fn main() {
println!("{}", c) println!("{}", c)
} }
} }
Mode::ConflictStep => {
println!("{}", p);
p.find_path();
println!("{}", p);
let mut c = ConflictAvoidance::new(p);
println!("{}", c);
while c.remove_conflict() {
println!("{}", c);
let mut s = String::new();
let _ = io::stdin().read_line(&mut s);
}
}
} }
} }

View file

@ -1,4 +1,4 @@
use std::fmt::Display; use std::{fmt::Display, ops::RangeInclusive};
use colored::Colorize; use colored::Colorize;
@ -49,6 +49,33 @@ impl ConflictAvoidance {
Self { map, belts } Self { map, belts }
} }
fn extend_range(
conflict_map: &Map<usize>,
xrange: &mut RangeInclusive<usize>,
yrange: &mut RangeInclusive<usize>,
) {
for x in xrange.clone() {
if *yrange.start() > 0 && *conflict_map.get(x, *yrange.start()) > 1 {
*yrange = *yrange.start() - 1..=*yrange.end();
return Self::extend_range(conflict_map, xrange, yrange);
}
if *yrange.end() < conflict_map.height - 1 && *conflict_map.get(x, *yrange.end()) > 1 {
*yrange = *yrange.start()..=*yrange.end() + 1;
return Self::extend_range(conflict_map, xrange, yrange);
}
}
for y in yrange.clone() {
if *xrange.start() > 0 && *conflict_map.get(*xrange.start(), y) > 1 {
*xrange = *xrange.start() - 1..=*xrange.end();
return Self::extend_range(conflict_map, xrange, yrange);
}
if *xrange.end() < conflict_map.width - 1 && *conflict_map.get(*xrange.end(), y) > 1 {
*xrange = *xrange.start()..=*xrange.end() + 1;
return Self::extend_range(conflict_map, xrange, yrange);
}
}
}
pub fn remove_conflict(&mut self) -> bool { pub fn remove_conflict(&mut self) -> bool {
let mut conflicts: Map<usize> = Map::new(self.map.width, self.map.height); let mut conflicts: Map<usize> = Map::new(self.map.width, self.map.height);
@ -110,21 +137,21 @@ impl ConflictAvoidance {
} }
}; };
let mut xoffset = 0; let xoffset = 1;
let mut yoffset = 0; let yoffset = 1;
let mut xrange = cx..=cx;
let mut yrange = cy..=cy;
loop { loop {
xoffset += 1; xrange = xrange.start().saturating_sub(xoffset)
yoffset += 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); ..=usize::min(xrange.end() + xoffset, self.map.width - 1);
let yrange = yrange.start().saturating_sub(yoffset) yrange = yrange.start().saturating_sub(yoffset)
..=usize::min(yrange.end() + yoffset, self.map.height - 1); ..=usize::min(yrange.end() + yoffset, self.map.height - 1);
println!("x: {:?}, y: {:?}", xrange, yrange);
Self::extend_range(&conflicts, &mut xrange, &mut yrange);
println!("x: {:?}, y: {:?}", xrange, yrange); println!("x: {:?}, y: {:?}", xrange, yrange);
let xsize = xrange.end() - xrange.start() + 1; let xsize = xrange.end() - xrange.start() + 1;
@ -163,11 +190,13 @@ impl ConflictAvoidance {
.position(|p| xrange.contains(&p.x) && yrange.contains(&p.y)) .position(|p| xrange.contains(&p.x) && yrange.contains(&p.y))
.map(|i| usize::min(path.len() - 1, path.len() - i)); .map(|i| usize::min(path.len() - 1, path.len() - i));
if let Some((start, end)) = s.zip(e) { if let Some((start, mut end)) = s.zip(e) {
// dbg!(start, end); // dbg!(start, end);
mapping.push((i, start, end)); if matches!(path[end - 1], PathField::Underground { .. }) {
end -= 1;
}
// dbg!(path[start], path[end]); mapping.push((i, start, end));
let (start_pos, start_dir) = path[start] let (start_pos, start_dir) = path[start]
.end_pos(&Dimension { .end_pos(&Dimension {
@ -179,6 +208,7 @@ impl ConflictAvoidance {
let end_dir = path[end].dir(); let end_dir = path[end].dir();
// dbg!(start_pos, end_pos); // dbg!(start_pos, end_pos);
// dbg!(i, path[start], path[end]);
b.add_path( b.add_path(
( (

View file

@ -27,15 +27,35 @@ where
} }
pub fn get(&self, x: usize, y: usize) -> &T { pub fn get(&self, x: usize, y: usize) -> &T {
assert!(x < self.width); assert!(
assert!(y < self.height); x < self.width,
"assertion failed: x < self.width; x: {}, self.width: {}",
x,
self.width
);
assert!(
y < self.height,
"assertion failed: y < self.height; y: {}, self.height: {}",
y,
self.height
);
let i = self.index(x, y); let i = self.index(x, y);
self.data.get(i).unwrap() self.data.get(i).unwrap()
} }
pub fn get_mut(&mut self, x: usize, y: usize) -> &mut T { pub fn get_mut(&mut self, x: usize, y: usize) -> &mut T {
assert!(x < self.width); assert!(
assert!(y < self.height); x < self.width,
"assertion failed: x < self.width; x: {}, self.width: {}",
x,
self.width
);
assert!(
y < self.height,
"assertion failed: y < self.height; y: {}, self.height: {}",
y,
self.height
);
let i = self.index(x, y); let i = self.index(x, y);
self.data.get_mut(i).unwrap() self.data.get_mut(i).unwrap()
} }