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::{
|
use factorio_blueprint::{
|
||||||
belt_finding::{
|
belt_finding::{
|
||||||
brute_force::{Bruteforce, PathField},
|
brute_force::{Bruteforce, BruteforceBuilder, PathField},
|
||||||
Direction, Position,
|
Direction, Position,
|
||||||
},
|
},
|
||||||
misc::Map,
|
misc::Map,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut b = Bruteforce {
|
let mut b = BruteforceBuilder::new(6, 8);
|
||||||
map: Map::new(5, 10),
|
|
||||||
path: vec![],
|
|
||||||
end_pos: Position::new(4, 9),
|
|
||||||
end_dir: Direction::Up,
|
|
||||||
count: 0,
|
|
||||||
solution_count: 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
b.apply_path_field(PathField::Belt {
|
b.add_path(
|
||||||
pos: Position::new(1, 0),
|
(Position::new(1, 0), Direction::Down),
|
||||||
dir: Direction::Down,
|
(Position::new(4, 6), Direction::Up),
|
||||||
});
|
);
|
||||||
|
|
||||||
b.map.get_mut(0, 2).blocked = true;
|
b.set_blocked_range(0, 2, 5, 5, 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.map.get_mut(0, 4).blocked = true;
|
let mut b = b.build();
|
||||||
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;
|
|
||||||
|
|
||||||
while b.next_finish_state() {
|
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 struct Bruteforce {
|
||||||
pub map: Map<BruteforceField>,
|
map: Map<BruteforceField>,
|
||||||
pub path: Vec<PathField>,
|
path: Vec<PathField>,
|
||||||
pub end_pos: Position,
|
end: (Position, Direction),
|
||||||
pub end_dir: Direction,
|
solution_count: u128,
|
||||||
pub solution_count: u128,
|
count: u128,
|
||||||
pub count: u128,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Bruteforce {
|
impl Bruteforce {
|
||||||
|
|
@ -113,27 +161,15 @@ impl Bruteforce {
|
||||||
match self.path.last().unwrap() {
|
match self.path.last().unwrap() {
|
||||||
PathField::Belt { pos, dir } => self
|
PathField::Belt { pos, dir } => self
|
||||||
.pos_in_direction(pos, dir, 1)
|
.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(),
|
.is_some(),
|
||||||
PathField::Underground { pos, dir, len } => self
|
PathField::Underground { pos, dir, len } => self
|
||||||
.pos_in_direction(pos, dir, *len as usize + 1)
|
.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(),
|
.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) {
|
fn path_field_end(&self, path_field: &PathField) -> (Position, Direction) {
|
||||||
match path_field {
|
match path_field {
|
||||||
PathField::Belt { pos, dir } => (*pos, *dir),
|
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)),
|
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 {
|
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
|
// Print body
|
||||||
|
|
||||||
for y in 0..self.map.height {
|
for y in 0..self.map.height {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue