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

View file

@ -4,6 +4,7 @@ use crate::misc::Map;
use crate::priority_queue::BinaryHeap;
use crate::Connection;
use crate::Map as _;
use crate::SinglePathInput;
use crate::{graph::wheighted_graph::shortest_path::dijkstra, SinglePathfinder};
use factorio_core::{prelude::*, visualize::Visualize};
use serde::{Deserialize, Serialize};
@ -17,23 +18,22 @@ pub struct ConflictAvoidance {
}
impl SinglePathfinder for ConflictAvoidance {
fn find_paths(
fn find_paths<M: crate::Map>(
&self,
input: &[crate::SingleConnection],
map: impl crate::Map,
input: SinglePathInput<'_, M>,
) -> 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);
for x in 0..size.x {
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);
}
}
}
for i in input {
for i in input.connections {
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() {
if i != without {
for p in path {
let weight = 1.0;
let weight = 10.0;
let x = p.0.x as usize;
let y = p.0.y as usize;

View file

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

View file

@ -6,6 +6,11 @@ pub mod graph;
pub mod misc;
pub mod priority_queue;
pub struct PathInput<'c, M> {
connections: &'c [Connection],
map: M,
}
pub struct Connection {
pub start_pos: Position,
pub start_dir: Direction,
@ -23,7 +28,12 @@ pub trait Map {
}
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 {
@ -35,15 +45,16 @@ struct SingleConnection {
}
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
where
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
.connections
.iter()
.flat_map(|c| {
(0..c.lanes).map(|i| SingleConnection {
@ -60,12 +71,16 @@ where
})
.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();
Some(
input
.connections
.iter()
.map(|i| inner_iterator.by_ref().take(i.lanes).flatten().collect())
.collect(),