87 lines
2.3 KiB
Rust
87 lines
2.3 KiB
Rust
use factorio_core::{beltoptions::Beltspeed, pathfield::PathField, prelude::*};
|
|
|
|
pub mod belt_finding;
|
|
pub mod examples;
|
|
|
|
pub struct PathInput<'c, M> {
|
|
pub connections: &'c [Connection],
|
|
pub map: M,
|
|
}
|
|
|
|
pub struct Connection {
|
|
pub start_pos: Position,
|
|
pub start_dir: Direction,
|
|
pub end_pos: Position,
|
|
pub end_dir: Direction,
|
|
pub beltspeed: Beltspeed,
|
|
pub lanes: usize,
|
|
}
|
|
|
|
pub trait Map {
|
|
/// Returns true if the position is useable
|
|
fn get_position(&self, pos: Position) -> bool;
|
|
/// Returns the relevant area as (pos, size)
|
|
fn area(&self) -> (Position, Position);
|
|
}
|
|
|
|
pub trait Pathfinder {
|
|
fn find_paths<M: Map>(&self, input: PathInput<'_, M>) -> Option<Vec<Vec<PathField>>>;
|
|
}
|
|
|
|
pub struct SinglePathInput<'c, M> {
|
|
connections: &'c [SingleConnection],
|
|
map: M,
|
|
}
|
|
|
|
struct SingleConnection {
|
|
pub start_pos: Position,
|
|
pub start_dir: Direction,
|
|
pub end_pos: Position,
|
|
pub end_dir: Direction,
|
|
#[allow(dead_code)]
|
|
pub beltspeed: Beltspeed,
|
|
}
|
|
|
|
trait SinglePathfinder {
|
|
fn find_paths<M: Map>(&self, input: SinglePathInput<'_, M>) -> Option<Vec<Vec<PathField>>>;
|
|
}
|
|
|
|
impl<P> Pathfinder for P
|
|
where
|
|
P: SinglePathfinder,
|
|
{
|
|
fn find_paths<M: Map>(&self, input: PathInput<'_, M>) -> Option<Vec<Vec<PathField>>> {
|
|
let inner_input = input
|
|
.connections
|
|
.iter()
|
|
.flat_map(|c| {
|
|
(0..c.lanes).map(|i| SingleConnection {
|
|
start_pos: c
|
|
.start_pos
|
|
.in_direction(&c.start_dir.clockwise(), i as PositionType),
|
|
start_dir: c.start_dir,
|
|
end_pos: c
|
|
.end_pos
|
|
.in_direction(&c.end_dir.clockwise(), i as PositionType),
|
|
end_dir: c.end_dir,
|
|
beltspeed: c.beltspeed,
|
|
})
|
|
})
|
|
.collect::<Vec<_>>();
|
|
|
|
let inner_result = self.find_paths(SinglePathInput {
|
|
connections: &inner_input,
|
|
map: input.map,
|
|
})?;
|
|
|
|
let mut inner_iterator = inner_result.into_iter();
|
|
|
|
Some(
|
|
input
|
|
.connections
|
|
.iter()
|
|
.map(|i| inner_iterator.by_ref().take(i.lanes).flatten().collect())
|
|
.collect(),
|
|
)
|
|
}
|
|
}
|