Add PathFinder trait

This commit is contained in:
hal8174 2025-01-28 21:54:20 +01:00
parent 5c8010c23b
commit 08eb0a8e11
8 changed files with 688 additions and 373 deletions

View file

@ -1,4 +1,74 @@
use factorio_core::{beltoptions::Beltspeed, pathfield::PathField, prelude::*};
pub mod belt_finding;
pub mod examples;
pub mod graph;
pub mod misc;
pub mod priority_queue;
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(&self, input: &[Connection], map: impl Map) -> Option<Vec<Vec<PathField>>>;
}
struct SingleConnection {
pub start_pos: Position,
pub start_dir: Direction,
pub end_pos: Position,
pub end_dir: Direction,
pub beltspeed: Beltspeed,
}
trait SinglePathfinder {
fn find_paths(&self, input: &[SingleConnection], map: impl Map) -> Option<Vec<Vec<PathField>>>;
}
impl<P> Pathfinder for P
where
P: SinglePathfinder,
{
fn find_paths(&self, input: &[Connection], map: impl Map) -> Option<Vec<Vec<PathField>>> {
let inner_input = input
.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.start_dir.clockwise(), i as PositionType),
end_dir: c.end_dir,
beltspeed: c.beltspeed,
})
})
.collect::<Vec<_>>();
let inner_result = self.find_paths(&inner_input, map)?;
let mut inner_iterator = inner_result.into_iter();
Some(
input
.iter()
.map(|i| inner_iterator.by_ref().take(i.lanes).flatten().collect())
.collect(),
)
}
}