76 lines
2.1 KiB
Rust
76 lines
2.1 KiB
Rust
use factorio_core::{misc::PositionMap, prelude::Position};
|
|
use factorio_graph::{
|
|
graph::Graph,
|
|
priority_queue::binary_heap::FastBinaryHeap,
|
|
set_cover::{greedy_connected_set_cover_priority_queue, greedy_set_cover_priority_queue},
|
|
};
|
|
|
|
use crate::abstraction::Entity;
|
|
|
|
use super::Blueprint;
|
|
|
|
struct RoboportGraph<'a> {
|
|
roboports: &'a [Position],
|
|
}
|
|
|
|
impl Graph for RoboportGraph<'_> {
|
|
type Node = usize;
|
|
|
|
fn edge(&self, node: &Self::Node, num: usize) -> Option<Self::Node> {
|
|
let p = self.roboports[*node];
|
|
self.roboports
|
|
.iter()
|
|
.enumerate()
|
|
.filter(|(_, other)| p.x.abs_diff(other.x) <= 100 && p.y.abs_diff(other.y) <= 100)
|
|
.nth(num)
|
|
.map(|(i, _)| i)
|
|
}
|
|
}
|
|
|
|
impl Blueprint {
|
|
pub fn add_roboport_network(&mut self) {
|
|
let aabb = self.get_aabb().unwrap();
|
|
|
|
let universe = self.entities.len();
|
|
|
|
let map = self.placibility_map();
|
|
|
|
let mut roboports = Vec::new();
|
|
|
|
let mut sets = Vec::new();
|
|
|
|
for (x, y) in (aabb.min().x..=aabb.max().x)
|
|
.filter(move |x| x.rem_euclid(2) == 0)
|
|
.flat_map(|x| {
|
|
(aabb.min().y..=aabb.max().y)
|
|
.filter(move |y| y.rem_euclid(2) == 0)
|
|
.map(move |y| (x, y))
|
|
})
|
|
{
|
|
if map.placeable(Position::new(x, y), Position::new(8, 8)) {
|
|
let mut coverage = Vec::new();
|
|
for (i, (_, e)) in self.entities.iter().enumerate() {
|
|
if e.position.x.abs_diff(x) <= 110 && e.position.y.abs_diff(y) <= 110 {
|
|
coverage.push(i);
|
|
}
|
|
}
|
|
|
|
roboports.push(Position::new(x, y));
|
|
sets.push(coverage);
|
|
}
|
|
}
|
|
|
|
dbg!(universe, sets.len());
|
|
let res = greedy_connected_set_cover_priority_queue::<_, _, FastBinaryHeap<_>>(
|
|
universe,
|
|
&sets,
|
|
RoboportGraph {
|
|
roboports: &roboports,
|
|
},
|
|
);
|
|
|
|
for r in res {
|
|
self.add_entity(Entity::new_roboport(roboports[r]));
|
|
}
|
|
}
|
|
}
|