Automatically sideload belt

This commit is contained in:
hal8174 2025-02-09 23:13:51 +01:00
parent 84d00238ab
commit 27783aa5c7
5 changed files with 302 additions and 42 deletions

View file

@ -0,0 +1,70 @@
subfactories:
- !SubFactory
recipe: military-science-pack
machines: 40
machine: assembly-machine-3
- !SubFactory
recipe: piercing-rounds-magazine
machines: 12
machine: assembly-machine-3
- !SubFactory
recipe: firearm-magazine
machines: 4
machine: assembly-machine-3
- !SubFactory
recipe: grenade
machines: 32
machine: assembly-machine-3
- !SubFactory
recipe: wall
machines: 4
machine: assembly-machine-3
- !ExternalConnection
inputs: 1
outputs: 6
factory_connections:
- item: military-science-pack
amount: 10
from: 0
to: 5
- item: piercing-rounds-magazine
amount: 5
from: 1
to: 0
- item: grenade
amount: 5
from: 3
to: 0
- item: wall
amount: 10
from: 4
to: 0
- item: firearm-magazine
amount: 5
from: 2
to: 1
- item: steel
amount: 5
from: 5
to: 1
- item: copper-plates
amount: 25
from: 5
to: 1
- item: iron-plates
amount: 20
from: 5
to: 2
- item: iron-plates
amount: 25
from: 5
to: 3
- item: coal
amount: 50
from: 5
to: 3
- item: stone-brick
amount: 50
from: 5
to: 4

View file

@ -0,0 +1,82 @@
subfactories:
- !SubFactory
recipe: logistic-science-pack
machines: 48
machine: assembly-machine-3
- !SubFactory
recipe: inserter
machines: 4
machine: assembly-machine-3
- !SubFactory
recipe: electronic-circuit
machines: 4
machine: assembly-machine-3
- !SubFactory
recipe: copper-cable
machines: 6
machine: assembly-machine-3
- !SubFactory
recipe: transport-belt
machines: 2
machine: assembly-machine-3
- !SubFactory
recipe: iron-gear-wheel
machines: 6
machine: assembly-machine-3
- !ExternalConnection
inputs: 1
outputs: 5
- !Splitter
factory_connections:
- item: logistic-science-pack
amount: 10
from: 0
to: 6
- item: inserter
amount: 10
from: 1
to: 0
- item: transport-belt
amount: 10
from: 4
to: 0
- item: electronic-circuits
amount: 10
from: 2
to: 1
- item: iron-gear-wheel
amount: 10
from: 7
to: 1
- item: iron-plate
amount: 10
from: 6
to: 1
- item: iron-plate
amount: 10
from: 6
to: 2
- item: copper-cable
amount: 30
from: 3
to: 2
- item: copper-plate
amount: 15
from: 6
to: 3
- item: iron-plate
amount: 5
from: 6
to: 4
- item: iron-gear-wheel
amount: 5
from: 7
to: 4
- item: iron-gear-wheel
amount: 15
from: 5
to: 7
- item: iron-plate
amount: 30
from: 6
to: 5

View file

@ -18,12 +18,11 @@ subfactories:
- !ExternalConnection
inputs: 1
outputs: 5
- !SideLoader
factory_connections:
- item: iron-gear-wheel
amount: 15
from: 0
to: 5
to: 3
- item: copper-cable
amount: 45
from: 1
@ -47,10 +46,6 @@ factory_connections:
- item: iron-plate
amount: 15
from: 4
to: 5
- item: iron-plate;iron-gear-wheel
amount: 30
from: 5
to: 3
- item: electronic-circuit
amount: 15

View file

@ -29,8 +29,8 @@ fn main() {
let l = ValidLayout {
max_tries: 4,
retries: 4,
start_size: Position::new(64, 64),
growth: Position::new(4, 4),
start_size: Position::new(128, 128),
growth: Position::new(16, 16),
};
let l = GeneticAlgorithm {
@ -38,7 +38,7 @@ fn main() {
population_size: 40,
population_keep: 8,
population_new: 2,
generations: 80,
generations: 40,
valid_layout: l,
};
let p = ConflictAvoidance {

View file

@ -4,7 +4,7 @@ use factorio_blueprint::abstraction::{Blueprint, Entity};
use factorio_core::{beltoptions::Beltspeed, prelude::*, visualize::Visualize};
use factorio_layout::{Connection, Interface, LayoutInput, Layouter, MacroBlock};
use factorio_pathfinding::Pathfinder;
use rand::Rng;
use rand::{Rng, seq::IndexedRandom};
use serde::{Deserialize, Serialize};
use crate::assembly::assembly_line_2_input;
@ -64,29 +64,113 @@ pub fn generate_factory<L: Layouter, P: Pathfinder>(
.filter(|&(_, c)| c.from == i)
.collect::<Vec<_>>();
let block_index = blocks.len();
match b {
Building::SubFactory {
recipe,
machines,
machine,
} => {
assert!(machine == "assembly-machine-3");
assert_eq!(machine, "assembly-machine-3");
assert_eq!(output_connections.len(), 1);
assert!(input_connections.len() <= 3);
let output_connection = output_connections.first().unwrap();
let intermediate_output_connection =
HashMap::from([(output_connection.0, (block_index, 0))]);
input_connections.sort_by(|a, b| b.1.amount.total_cmp(&a.1.amount));
let (input_belt1, input_belt2, addition_blocks) = if let Some(
&[
(connection_id0, c0),
(connection_id1, c1),
(connection_id2, c2),
],
) =
input_connections.first_chunk()
{
let c0_bigger = c0.amount > c1.amount + c2.amount;
intermediate_connections.push(dbg!((
HashMap::from([
(connection_id0, (block_index, if c0_bigger { 1 } else { 0 })),
(connection_id1, (block_index + 1, 0)),
(connection_id2, (block_index + 1, 1)),
]),
intermediate_output_connection,
)));
let beltspeed =
Beltspeed::from_items_per_second(2.0 * f64::max(c1.amount, c2.amount));
connections.push(Connection {
startblock: block_index + 1,
startpoint: 0,
endblock: block_index,
endpoint: if c0_bigger { 0 } else { 1 },
lanes: 1,
beltspeed,
});
let mut b = Blueprint::new();
b.add_entity(Entity::new_belt(
beltspeed,
Position::new(1, 1),
Direction::Up,
));
(
Beltspeed::from_items_per_second(c0.amount),
Some(beltspeed),
vec![(
MacroBlock {
size: Position::new(1, 1),
input: vec![
Interface {
offset: Position::new(0, 0),
dir: Direction::Right,
},
Interface {
offset: Position::new(0, 0),
dir: Direction::Left,
},
],
output: vec![Interface {
offset: Position::new(0, 0),
dir: Direction::Up,
}],
},
b,
)],
)
} else if let Some(&[(connection_id0, c0), (connection_id1, c1)]) =
input_connections.first_chunk()
{
intermediate_connections.push(dbg!((
HashMap::from([
(connection_id0, (block_index, 0)),
(connection_id1, (block_index, 1)),
]),
intermediate_output_connection,
)));
(
Beltspeed::from_items_per_second(c0.amount),
Some(Beltspeed::from_items_per_second(c1.amount)),
vec![],
)
} else if let Some(&[(connection_id, c)]) = input_connections.first_chunk() {
intermediate_connections.push((
HashMap::from([(connection_id, (block_index, 0))]),
intermediate_output_connection,
));
(Beltspeed::from_items_per_second(c.amount), None, vec![])
} else {
unreachable!()
};
let (b, size, y_output, y_inputs) = assembly_line_2_input(
*machines,
recipe,
Beltspeed::from_items_per_second(
input_connections
.first()
.map(|&(_, c)| c.amount)
.unwrap_or(1.0),
),
if let Some(&(_, c)) = input_connections.get(1) {
Some(Beltspeed::from_items_per_second(c.amount))
} else {
None
},
input_belt1,
input_belt2,
Beltspeed::from_items_per_second(
output_connections
.first()
@ -110,6 +194,11 @@ pub fn generate_factory<L: Layouter, P: Pathfinder>(
dir: Direction::Left,
}],
});
for (mb, b) in addition_blocks {
blueprints.push(b);
blocks.push(mb);
}
}
Building::ExternalConnection { inputs, outputs } => {
blocks.push(MacroBlock {
@ -129,6 +218,18 @@ pub fn generate_factory<L: Layouter, P: Pathfinder>(
});
blueprints.push(Blueprint::new());
intermediate_connections.push((
input_connections
.iter()
.enumerate()
.map(|(port, &(connection_id, _))| (connection_id, (block_index, port)))
.collect::<HashMap<_, _>>(),
output_connections
.iter()
.enumerate()
.map(|(port, &(connection_id, _))| (connection_id, (block_index, port)))
.collect::<HashMap<_, _>>(),
));
}
Building::SideLoader => {
let mut blueprint = Blueprint::new();
@ -161,6 +262,18 @@ pub fn generate_factory<L: Layouter, P: Pathfinder>(
}],
});
blueprints.push(blueprint);
intermediate_connections.push((
input_connections
.iter()
.enumerate()
.map(|(port, &(connection_id, _))| (connection_id, (block_index, port)))
.collect::<HashMap<_, _>>(),
output_connections
.iter()
.enumerate()
.map(|(port, &(connection_id, _))| (connection_id, (block_index, port)))
.collect::<HashMap<_, _>>(),
));
}
Building::Splitter => {
let mut blueprint = Blueprint::new();
@ -196,37 +309,37 @@ pub fn generate_factory<L: Layouter, P: Pathfinder>(
],
});
blueprints.push(blueprint);
intermediate_connections.push((
input_connections
.iter()
.enumerate()
.map(|(port, &(connection_id, _))| (connection_id, (block_index, port)))
.collect::<HashMap<_, _>>(),
output_connections
.iter()
.enumerate()
.map(|(port, &(connection_id, _))| (connection_id, (block_index, port)))
.collect::<HashMap<_, _>>(),
));
}
}
let input_connection_map = input_connections
.iter()
.enumerate()
.map(|(port, &(connection_id, _))| (connection_id, port))
.collect::<HashMap<_, _>>();
let output_connection_map = output_connections
.iter()
.enumerate()
.map(|(port, &(connection_id, _))| (connection_id, port))
.collect::<HashMap<_, _>>();
intermediate_connections.push((input_connection_map, output_connection_map));
}
dbg!(&intermediate_connections);
for (i, c) in factory_graph.factory_connections.iter().enumerate() {
dbg!(i, c);
connections.push(Connection {
startblock: c.from,
startpoint: intermediate_connections[c.from].1[&i],
endblock: c.to,
endpoint: intermediate_connections[c.to].0[&i],
startblock: intermediate_connections[c.from].1[&i].0,
startpoint: intermediate_connections[c.from].1[&i].1,
endblock: intermediate_connections[c.to].0[&i].0,
endpoint: intermediate_connections[c.to].0[&i].1,
lanes: 1,
beltspeed: Beltspeed::from_items_per_second(c.amount),
});
}
// dbg!(&blocks);
// dbg!(&connections);
dbg!(&blocks);
dbg!(&connections);
let layout_input = LayoutInput {
blocks,