Refactor bruteforce interface

This commit is contained in:
hal8174 2023-12-11 20:23:32 +01:00
parent 2bc323aa58
commit 20073b88ce
2 changed files with 76 additions and 45 deletions

View file

@ -1,39 +1,24 @@
use factorio_blueprint::{
belt_finding::{
brute_force::{Bruteforce, PathField},
brute_force::{Bruteforce, BruteforceBuilder, PathField},
Direction, Position,
},
misc::Map,
};
fn main() {
let mut b = Bruteforce {
map: Map::new(5, 10),
path: vec![],
end_pos: Position::new(4, 9),
end_dir: Direction::Up,
count: 0,
solution_count: 0,
};
let mut b = BruteforceBuilder::new(6, 8);
b.apply_path_field(PathField::Belt {
pos: Position::new(1, 0),
dir: Direction::Down,
});
b.add_path(
(Position::new(1, 0), Direction::Down),
(Position::new(4, 6), Direction::Up),
);
b.map.get_mut(0, 2).blocked = true;
b.map.get_mut(1, 2).blocked = true;
b.map.get_mut(2, 2).blocked = true;
b.map.get_mut(3, 2).blocked = true;
b.map.get_mut(4, 2).blocked = true;
b.set_blocked_range(0, 2, 5, 5, true);
b.map.get_mut(0, 4).blocked = true;
b.map.get_mut(1, 4).blocked = true;
b.map.get_mut(2, 4).blocked = true;
b.map.get_mut(3, 4).blocked = true;
b.map.get_mut(4, 4).blocked = true;
let mut b = b.build();
while b.next_finish_state() {
println!("{}\n{}\n{}", b.count, b.solution_count, b);
println!("{}\n{}\n{}", b.count(), b.solution_count(), b);
}
}

View file

@ -50,15 +50,63 @@ impl PathField {
}
}
static MAX_UNDERGROUND_LENGTH: u8 = 5;
static MAX_UNDERGROUND_LENGTH: u8 = 6;
pub struct BruteforceBuilder {
map: Map<BruteforceField>,
path: Vec<[(Position, Direction); 2]>,
}
impl BruteforceBuilder {
pub fn new(width: usize, height: usize) -> Self {
Self {
map: Map::new(width, height),
path: Vec::new(),
}
}
pub fn add_path(&mut self, start: (Position, Direction), end: (Position, Direction)) {
self.path.push([start, end]);
}
pub fn set_blocked(&mut self, x: usize, y: usize, blocked: bool) {
self.map.get_mut(x, y).blocked = blocked;
}
pub fn set_blocked_range(&mut self, x1: usize, y1: usize, x2: usize, y2: usize, blocked: bool) {
for x in x1..=x2 {
for y in y1..=y2 {
self.set_blocked(x, y, blocked);
}
}
}
pub fn build(self) -> Bruteforce {
let mut b = Bruteforce {
map: self.map,
path: Vec::new(),
end: self.path[0][1],
solution_count: 0,
count: 0,
};
b.apply_path_field(PathField::Belt {
pos: self.path[0][0].0,
dir: self.path[0][0].1,
});
b.map.get_mut(self.path[0][1].0.x, self.path[0][1].0.y);
b
}
}
pub struct Bruteforce {
pub map: Map<BruteforceField>,
pub path: Vec<PathField>,
pub end_pos: Position,
pub end_dir: Direction,
pub solution_count: u128,
pub count: u128,
map: Map<BruteforceField>,
path: Vec<PathField>,
end: (Position, Direction),
solution_count: u128,
count: u128,
}
impl Bruteforce {
@ -113,27 +161,15 @@ impl Bruteforce {
match self.path.last().unwrap() {
PathField::Belt { pos, dir } => self
.pos_in_direction(pos, dir, 1)
.filter(|p| p == &self.end_pos && dir != &self.end_dir.reverse())
.filter(|p| p == &self.end.0 && dir != &self.end.1.reverse())
.is_some(),
PathField::Underground { pos, dir, len } => self
.pos_in_direction(pos, dir, *len as usize + 1)
.filter(|p| p == &self.end_pos && dir != &self.end_dir.reverse())
.filter(|p| p == &self.end.0 && dir != &self.end.1.reverse())
.is_some(),
}
}
fn next_state_internal(&mut self, pos: Position, dir: Direction) -> bool {
if let Some(next_pos) = self
.pos_in_direction(&pos, &dir, 1)
.filter(|p| !self.map.get(p.x, p.y).blocked)
{
self.apply_path_field(PathField::Belt { pos: next_pos, dir });
true
} else {
false
}
}
fn path_field_end(&self, path_field: &PathField) -> (Position, Direction) {
match path_field {
PathField::Belt { pos, dir } => (*pos, *dir),
@ -246,6 +282,14 @@ impl Bruteforce {
Direction::Left => pos.x.checked_sub(len).map(|x| Position::new(x, pos.y)),
}
}
pub fn count(&self) -> u128 {
self.count
}
pub fn solution_count(&self) -> u128 {
self.solution_count
}
}
impl Display for Bruteforce {
@ -301,6 +345,8 @@ impl Display for Bruteforce {
}
}
m.set(self.end.0.x, self.end.0.y, Some((0, "t")));
// Print body
for y in 0..self.map.height {