From 27783aa5c7685a86179d2e7e66b22cf9a03f3f8e Mon Sep 17 00:00:00 2001 From: hal8174 Date: Sun, 9 Feb 2025 23:13:51 +0100 Subject: [PATCH] Automatically sideload belt --- .../factory_graph_black_science.yml | 70 +++++++ .../factory_graph_green_science.yml | 82 ++++++++ .../factory_graph_inserter.yml | 7 +- .../src/bin/generate_factory.rs | 6 +- factorio-blueprint-generator/src/factory.rs | 179 ++++++++++++++---- 5 files changed, 302 insertions(+), 42 deletions(-) create mode 100644 factorio-blueprint-generator/factory_graph_black_science.yml create mode 100644 factorio-blueprint-generator/factory_graph_green_science.yml diff --git a/factorio-blueprint-generator/factory_graph_black_science.yml b/factorio-blueprint-generator/factory_graph_black_science.yml new file mode 100644 index 0000000..d728e76 --- /dev/null +++ b/factorio-blueprint-generator/factory_graph_black_science.yml @@ -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 + diff --git a/factorio-blueprint-generator/factory_graph_green_science.yml b/factorio-blueprint-generator/factory_graph_green_science.yml new file mode 100644 index 0000000..de73b59 --- /dev/null +++ b/factorio-blueprint-generator/factory_graph_green_science.yml @@ -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 diff --git a/factorio-blueprint-generator/factory_graph_inserter.yml b/factorio-blueprint-generator/factory_graph_inserter.yml index 1d00af3..4f2fb3c 100644 --- a/factorio-blueprint-generator/factory_graph_inserter.yml +++ b/factorio-blueprint-generator/factory_graph_inserter.yml @@ -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 diff --git a/factorio-blueprint-generator/src/bin/generate_factory.rs b/factorio-blueprint-generator/src/bin/generate_factory.rs index 0d25324..54a9cfd 100644 --- a/factorio-blueprint-generator/src/bin/generate_factory.rs +++ b/factorio-blueprint-generator/src/bin/generate_factory.rs @@ -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 { diff --git a/factorio-blueprint-generator/src/factory.rs b/factorio-blueprint-generator/src/factory.rs index bbb4270..fe5cd23 100644 --- a/factorio-blueprint-generator/src/factory.rs +++ b/factorio-blueprint-generator/src/factory.rs @@ -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( .filter(|&(_, c)| c.from == i) .collect::>(); + 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( 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( }); blueprints.push(Blueprint::new()); + intermediate_connections.push(( + input_connections + .iter() + .enumerate() + .map(|(port, &(connection_id, _))| (connection_id, (block_index, port))) + .collect::>(), + output_connections + .iter() + .enumerate() + .map(|(port, &(connection_id, _))| (connection_id, (block_index, port))) + .collect::>(), + )); } Building::SideLoader => { let mut blueprint = Blueprint::new(); @@ -161,6 +262,18 @@ pub fn generate_factory( }], }); blueprints.push(blueprint); + intermediate_connections.push(( + input_connections + .iter() + .enumerate() + .map(|(port, &(connection_id, _))| (connection_id, (block_index, port))) + .collect::>(), + output_connections + .iter() + .enumerate() + .map(|(port, &(connection_id, _))| (connection_id, (block_index, port))) + .collect::>(), + )); } Building::Splitter => { let mut blueprint = Blueprint::new(); @@ -196,37 +309,37 @@ pub fn generate_factory( ], }); blueprints.push(blueprint); + intermediate_connections.push(( + input_connections + .iter() + .enumerate() + .map(|(port, &(connection_id, _))| (connection_id, (block_index, port))) + .collect::>(), + output_connections + .iter() + .enumerate() + .map(|(port, &(connection_id, _))| (connection_id, (block_index, port))) + .collect::>(), + )); } } - - let input_connection_map = input_connections - .iter() - .enumerate() - .map(|(port, &(connection_id, _))| (connection_id, port)) - .collect::>(); - - let output_connection_map = output_connections - .iter() - .enumerate() - .map(|(port, &(connection_id, _))| (connection_id, port)) - .collect::>(); - - 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,