Add multistation to factory

This commit is contained in:
hal8174 2025-03-01 22:31:35 +01:00
parent 41a528a49c
commit 5f5fe0c149
8 changed files with 98 additions and 46 deletions

View file

@ -16,12 +16,10 @@ subfactories:
machines: 32 machines: 32
machine: assembly-machine-3 machine: assembly-machine-3
- !SubFactory - !SubFactory
recipe: wall recipe: stone-wall
machines: 4 machines: 4
machine: assembly-machine-3 machine: assembly-machine-3
- !ExternalConnection - !ExternalConnection
inputs: 1
outputs: 6
factory_connections: factory_connections:
- item: military-science-pack - item: military-science-pack
amount: 10 amount: 10

View file

@ -40,8 +40,6 @@ subfactories:
machines: 10 machines: 10
machine: assembly-machine-3 machine: assembly-machine-3
- !ExternalConnection - !ExternalConnection
inputs: 1
outputs: 10
- !Splitter - !Splitter
- !Splitter - !Splitter
- !Splitter - !Splitter

View file

@ -22,8 +22,6 @@ subfactories:
machine: assembly-machine-3 machine: assembly-machine-3
- !SideLoader - !SideLoader
- !ExternalConnection - !ExternalConnection
inputs: 1
outputs: 8
- !SideLoader - !SideLoader
factory_connections: factory_connections:
- item: iron-gear-wheel - item: iron-gear-wheel

View file

@ -24,8 +24,6 @@ subfactories:
machines: 6 machines: 6
machine: assembly-machine-3 machine: assembly-machine-3
- !ExternalConnection - !ExternalConnection
inputs: 1
outputs: 5
- !Splitter - !Splitter
factory_connections: factory_connections:
- item: logistic-science-pack - item: logistic-science-pack

View file

@ -16,8 +16,6 @@ subfactories:
machines: 6 machines: 6
machine: assembly-machine-3 machine: assembly-machine-3
- !ExternalConnection - !ExternalConnection
inputs: 1
outputs: 5
factory_connections: factory_connections:
- item: iron-gear-wheel - item: iron-gear-wheel
amount: 15 amount: 15

View file

@ -7,7 +7,10 @@ use factorio_pathfinding::Pathfinder;
use rand::{Rng, SeedableRng, seq::IndexedRandom}; use rand::{Rng, SeedableRng, seq::IndexedRandom};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::assembly::assembly_line_2_input; use crate::{
assembly::assembly_line_2_input,
multistation::{StationSpec, multistation},
};
#[derive(Debug, Serialize, Deserialize, Clone)] #[derive(Debug, Serialize, Deserialize, Clone)]
pub struct FactoryGraph { pub struct FactoryGraph {
@ -22,10 +25,7 @@ pub enum Building {
machines: usize, machines: usize,
machine: String, machine: String,
}, },
ExternalConnection { ExternalConnection,
inputs: usize,
outputs: usize,
},
Splitter, Splitter,
SideLoader, SideLoader,
} }
@ -59,8 +59,9 @@ pub fn generate_factory<L: Layouter, P: Pathfinder + Sync, R: Rng + SeedableRng
let mut connections = Vec::new(); let mut connections = Vec::new();
let mut intermediate_connections = Vec::new(); let mut intermediate_connections = Vec::new();
let mut static_input = Vec::new(); let mut static_input_offset = 0;
let mut static_output = Vec::new(); let mut static_output_offset = 0;
let mut station_spec = Vec::new();
for (i, b) in factory_graph.subfactories.iter().enumerate() { for (i, b) in factory_graph.subfactories.iter().enumerate() {
let mut input_connections = factory_graph let mut input_connections = factory_graph
@ -254,25 +255,39 @@ pub fn generate_factory<L: Layouter, P: Pathfinder + Sync, R: Rng + SeedableRng
blocks.push(mb); blocks.push(mb);
} }
} }
Building::ExternalConnection { inputs, outputs } => { Building::ExternalConnection => {
let step = 4; let step = 1;
let static_input_offset = static_input.len(); // static_input.extend((0..*inputs).map(|y| Interface {
let static_output_offset = static_output.len(); // offset: Position::new(
static_input.extend((0..*inputs).map(|y| Interface { // -1,
offset: Position::new( // step * (y + static_input_offset + static_output_offset) as PositionType,
0, // ),
step * (y + static_input_offset + static_output_offset) as PositionType, // dir: Direction::Left,
), // }));
dir: Direction::Left, // static_output.extend((0..*outputs).map(|y| Interface {
// offset: Position::new(
// -1,
// step * (y + static_input_offset + static_output_offset + inputs)
// as PositionType,
// ),
// dir: Direction::Right,
// }));
station_spec.extend(input_connections.iter().map(|&(_, c)| StationSpec {
locomotives: 2,
wagons: 4,
load: true,
beltspeed: Beltspeed::from_items_per_second(c.amount),
lanes: 1,
})); }));
static_output.extend((0..*outputs).map(|y| Interface { station_spec.extend(output_connections.iter().map(|&(_, c)| StationSpec {
offset: Position::new( locomotives: 2,
0, wagons: 4,
step * (y + static_input_offset + static_output_offset + inputs) load: false,
as PositionType, beltspeed: Beltspeed::from_items_per_second(c.amount),
), lanes: 1,
dir: Direction::Right,
})); }));
intermediate_connections.push(IntermediateConnection { intermediate_connections.push(IntermediateConnection {
input: input_connections input: input_connections
.iter() .iter()
@ -301,6 +316,8 @@ pub fn generate_factory<L: Layouter, P: Pathfinder + Sync, R: Rng + SeedableRng
}) })
.collect::<HashMap<_, _>>(), .collect::<HashMap<_, _>>(),
}); });
static_input_offset += input_connections.len();
static_output_offset += output_connections.len();
} }
Building::SideLoader => { Building::SideLoader => {
let mut blueprint = Blueprint::new(); let mut blueprint = Blueprint::new();
@ -449,6 +466,44 @@ pub fn generate_factory<L: Layouter, P: Pathfinder + Sync, R: Rng + SeedableRng
// dbg!(&blocks); // dbg!(&blocks);
// dbg!(&connections); // dbg!(&connections);
let (multistation_blueprint, multistation_x_offset, mut multistation_y_offsets) =
multistation(&station_spec, 8);
let multistation_y_offset = multistation_y_offsets[0];
multistation_y_offsets.iter_mut().for_each(move |y| {
*y -= multistation_y_offset;
});
let static_input = station_spec
.iter()
.zip(multistation_y_offsets.iter())
.filter_map(|(s, y)| {
if s.load {
Some(Interface {
offset: Position::new(-1, y / 2),
dir: Direction::Left,
})
} else {
None
}
})
.collect();
let static_output = station_spec
.iter()
.zip(multistation_y_offsets.iter())
.filter_map(|(s, y)| {
if !s.load {
Some(Interface {
offset: Position::new(-1, y / 2),
dir: Direction::Right,
})
} else {
None
}
})
.collect();
let layout_input = LayoutInput { let layout_input = LayoutInput {
static_input, static_input,
static_output, static_output,
@ -476,5 +531,12 @@ pub fn generate_factory<L: Layouter, P: Pathfinder + Sync, R: Rng + SeedableRng
b.add_path(&path[1..], connection.beltspeed); b.add_path(&path[1..], connection.beltspeed);
} }
b.transform(Transformation::new(
Direction::Up,
Position::new(multistation_x_offset, multistation_y_offset - 2),
));
b.add_blueprint(multistation_blueprint);
b b
} }

View file

@ -633,7 +633,7 @@ pub fn multistation(
} }
} }
blueprint.transform(Transformation::new(Direction::Right, Position::new(0, 0))); // blueprint.transform(Transformation::new(Direction::Right, Position::new(0, 0)));
(blueprint, outrail_x + 5, output_heights) (blueprint, outrail_x + 5, output_heights)
} }

View file

@ -1,16 +1,16 @@
use crate::examples::HashMapMap;
use crate::graph::wheighted_graph::shortest_path::a_star;
use crate::graph::wheighted_graph::WheightedGraph;
use crate::misc::Map;
use crate::priority_queue::binary_heap::FastBinaryHeap;
use crate::Connection; use crate::Connection;
use crate::Map as _; use crate::Map as _;
use crate::SinglePathInput; use crate::SinglePathInput;
use crate::SinglePathfinder; use crate::SinglePathfinder;
use crate::examples::HashMapMap;
use crate::graph::wheighted_graph::WheightedGraph;
use crate::graph::wheighted_graph::shortest_path::a_star;
use crate::misc::Map;
use crate::priority_queue::binary_heap::FastBinaryHeap;
use factorio_core::{prelude::*, visualize::Visualize}; use factorio_core::{prelude::*, visualize::Visualize};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tracing::span;
use tracing::Level; use tracing::Level;
use tracing::span;
pub mod brute_force; pub mod brute_force;
@ -119,8 +119,8 @@ impl Problem {
} }
for (i, path) in self.path.iter().enumerate() { for (i, path) in self.path.iter().enumerate() {
if i != without { if i != without && !path.is_empty() {
for p in path { for p in &path[1..] {
let weight = 1000.0; let weight = 1000.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;
@ -238,8 +238,8 @@ impl WheightedGraph for MapInternal<'_> {
let penalty = self.map.get(next.x as usize, next.y as usize).weight; let penalty = self.map.get(next.x as usize, next.y as usize).weight;
match num { match num {
0 => Some(((next, node.1), 1.5 + penalty)), 0 => Some(((next, node.1), 1.5 + penalty)),
1 => Some(((next, node.1.counter_clockwise()), 1.5 + penalty)), 1 => Some(((next, node.1.counter_clockwise()), 2.0 + penalty)),
2 => Some(((next, node.1.clockwise()), 1.5 + penalty)), 2 => Some(((next, node.1.clockwise()), 2.0 + penalty)),
_ => { _ => {
let mut count = 2; let mut count = 2;
for l in 2..=6 { for l in 2..=6 {