Add type for Pathfinder input

This commit is contained in:
hal8174 2025-01-29 23:05:07 +01:00
parent 08eb0a8e11
commit 00eda50872
4 changed files with 29 additions and 12 deletions

View file

@ -259,7 +259,7 @@ impl ConflictAvoidance {
let mut b = b.build(); let mut b = b.build();
// self.print_visualization(); // b.print_visualization();
let mut min_cost = f64::INFINITY; let mut min_cost = f64::INFINITY;
let mut solutions = Vec::new(); let mut solutions = Vec::new();
@ -267,6 +267,7 @@ impl ConflictAvoidance {
while b.next_finish_state(timeout) { while b.next_finish_state(timeout) {
// println!("{}", b); // println!("{}", b);
// b.print(); // b.print();
b.print_visualization();
let c = b.cost(); let c = b.cost();
if c < min_cost { if c < min_cost {
min_cost = c; min_cost = c;

View file

@ -4,6 +4,7 @@ use crate::misc::Map;
use crate::priority_queue::BinaryHeap; use crate::priority_queue::BinaryHeap;
use crate::Connection; use crate::Connection;
use crate::Map as _; use crate::Map as _;
use crate::SinglePathInput;
use crate::{graph::wheighted_graph::shortest_path::dijkstra, SinglePathfinder}; use crate::{graph::wheighted_graph::shortest_path::dijkstra, SinglePathfinder};
use factorio_core::{prelude::*, visualize::Visualize}; use factorio_core::{prelude::*, visualize::Visualize};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -17,23 +18,22 @@ pub struct ConflictAvoidance {
} }
impl SinglePathfinder for ConflictAvoidance { impl SinglePathfinder for ConflictAvoidance {
fn find_paths( fn find_paths<M: crate::Map>(
&self, &self,
input: &[crate::SingleConnection], input: SinglePathInput<'_, M>,
map: impl crate::Map,
) -> Option<Vec<Vec<factorio_core::pathfield::PathField>>> { ) -> Option<Vec<Vec<factorio_core::pathfield::PathField>>> {
let (pos, size) = map.area(); let (pos, size) = input.map.area();
let mut p = Problem::new(size.x as usize, size.y as usize); let mut p = Problem::new(size.x as usize, size.y as usize);
for x in 0..size.x { for x in 0..size.x {
for y in 0..size.y { for y in 0..size.y {
if !map.get_position(Position::new(x - pos.x, y - pos.y)) { if !input.map.get_position(Position::new(x - pos.x, y - pos.y)) {
p.set_blocked(x as usize, y as usize, true); p.set_blocked(x as usize, y as usize, true);
} }
} }
} }
for i in input { for i in input.connections {
p.add_connection((i.start_pos, i.start_dir), (i.end_pos, i.end_dir)); p.add_connection((i.start_pos, i.start_dir), (i.end_pos, i.end_dir));
} }
@ -109,7 +109,7 @@ impl Problem {
for (i, path) in self.path.iter().enumerate() { for (i, path) in self.path.iter().enumerate() {
if i != without { if i != without {
for p in path { for p in path {
let weight = 1.0; let weight = 10.0;
let x = p.0.x as usize; let x = p.0.x as usize;
let y = p.0.y as usize; let y = p.0.y as usize;

View file

@ -76,6 +76,7 @@ fn main() {
Mode::ConflictAvoidance => { Mode::ConflictAvoidance => {
p.print_visualization(); p.print_visualization();
p.find_path(); p.find_path();
p.print_visualization();
p.find_path(); p.find_path();
p.print_visualization(); p.print_visualization();
let mut c = ConflictAvoidance::new(&p); let mut c = ConflictAvoidance::new(&p);

View file

@ -6,6 +6,11 @@ pub mod graph;
pub mod misc; pub mod misc;
pub mod priority_queue; pub mod priority_queue;
pub struct PathInput<'c, M> {
connections: &'c [Connection],
map: M,
}
pub struct Connection { pub struct Connection {
pub start_pos: Position, pub start_pos: Position,
pub start_dir: Direction, pub start_dir: Direction,
@ -23,7 +28,12 @@ pub trait Map {
} }
pub trait Pathfinder { pub trait Pathfinder {
fn find_paths(&self, input: &[Connection], map: impl Map) -> Option<Vec<Vec<PathField>>>; 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 { struct SingleConnection {
@ -35,15 +45,16 @@ struct SingleConnection {
} }
trait SinglePathfinder { trait SinglePathfinder {
fn find_paths(&self, input: &[SingleConnection], map: impl Map) -> Option<Vec<Vec<PathField>>>; fn find_paths<M: Map>(&self, input: SinglePathInput<'_, M>) -> Option<Vec<Vec<PathField>>>;
} }
impl<P> Pathfinder for P impl<P> Pathfinder for P
where where
P: SinglePathfinder, P: SinglePathfinder,
{ {
fn find_paths(&self, input: &[Connection], map: impl Map) -> Option<Vec<Vec<PathField>>> { fn find_paths<M: Map>(&self, input: PathInput<'_, M>) -> Option<Vec<Vec<PathField>>> {
let inner_input = input let inner_input = input
.connections
.iter() .iter()
.flat_map(|c| { .flat_map(|c| {
(0..c.lanes).map(|i| SingleConnection { (0..c.lanes).map(|i| SingleConnection {
@ -60,12 +71,16 @@ where
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let inner_result = self.find_paths(&inner_input, map)?; let inner_result = self.find_paths(SinglePathInput {
connections: &inner_input,
map: input.map,
})?;
let mut inner_iterator = inner_result.into_iter(); let mut inner_iterator = inner_result.into_iter();
Some( Some(
input input
.connections
.iter() .iter()
.map(|i| inner_iterator.by_ref().take(i.lanes).flatten().collect()) .map(|i| inner_iterator.by_ref().take(i.lanes).flatten().collect())
.collect(), .collect(),