Refactor bruteforce interface
This commit is contained in:
parent
2bc323aa58
commit
20073b88ce
2 changed files with 76 additions and 45 deletions
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue