Simple complete conflict avoidance.
This commit is contained in:
parent
993fb0730c
commit
2e9c699600
3 changed files with 83 additions and 18 deletions
|
|
@ -1,3 +1,5 @@
|
|||
use std::io;
|
||||
|
||||
use clap::{Parser, ValueEnum};
|
||||
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 {
|
||||
Solve,
|
||||
ConflictAvoidance,
|
||||
ConflictStep,
|
||||
}
|
||||
|
||||
#[derive(ValueEnum, Clone)]
|
||||
|
|
@ -51,5 +54,17 @@ fn main() {
|
|||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use std::fmt::Display;
|
||||
use std::{fmt::Display, ops::RangeInclusive};
|
||||
|
||||
use colored::Colorize;
|
||||
|
||||
|
|
@ -49,6 +49,33 @@ impl ConflictAvoidance {
|
|||
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 {
|
||||
let mut conflicts: Map<usize> = Map::new(self.map.width, self.map.height);
|
||||
|
||||
|
|
@ -110,21 +137,21 @@ impl ConflictAvoidance {
|
|||
}
|
||||
};
|
||||
|
||||
let mut xoffset = 0;
|
||||
let mut yoffset = 0;
|
||||
let xoffset = 1;
|
||||
let yoffset = 1;
|
||||
|
||||
let mut xrange = cx..=cx;
|
||||
let mut yrange = cy..=cy;
|
||||
|
||||
loop {
|
||||
xoffset += 1;
|
||||
yoffset += 1;
|
||||
|
||||
let xrange = cx..=cx;
|
||||
let yrange = cy..=cy;
|
||||
|
||||
let xrange = xrange.start().saturating_sub(xoffset)
|
||||
xrange = xrange.start().saturating_sub(xoffset)
|
||||
..=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);
|
||||
|
||||
println!("x: {:?}, y: {:?}", xrange, yrange);
|
||||
Self::extend_range(&conflicts, &mut xrange, &mut yrange);
|
||||
|
||||
println!("x: {:?}, y: {:?}", xrange, yrange);
|
||||
|
||||
let xsize = xrange.end() - xrange.start() + 1;
|
||||
|
|
@ -163,11 +190,13 @@ impl ConflictAvoidance {
|
|||
.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) {
|
||||
if let Some((start, mut end)) = s.zip(e) {
|
||||
// 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]
|
||||
.end_pos(&Dimension {
|
||||
|
|
@ -179,6 +208,7 @@ impl ConflictAvoidance {
|
|||
let end_dir = path[end].dir();
|
||||
|
||||
// dbg!(start_pos, end_pos);
|
||||
// dbg!(i, path[start], path[end]);
|
||||
|
||||
b.add_path(
|
||||
(
|
||||
|
|
|
|||
|
|
@ -27,15 +27,35 @@ where
|
|||
}
|
||||
|
||||
pub fn get(&self, x: usize, y: usize) -> &T {
|
||||
assert!(x < self.width);
|
||||
assert!(y < self.height);
|
||||
assert!(
|
||||
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);
|
||||
self.data.get(i).unwrap()
|
||||
}
|
||||
|
||||
pub fn get_mut(&mut self, x: usize, y: usize) -> &mut T {
|
||||
assert!(x < self.width);
|
||||
assert!(y < self.height);
|
||||
assert!(
|
||||
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);
|
||||
self.data.get_mut(i).unwrap()
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue