Progress with factory generation from factory graph
This commit is contained in:
parent
0ab97485bb
commit
0f8bf5000c
8 changed files with 613 additions and 81 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
|
@ -569,7 +569,9 @@ dependencies = [
|
||||||
"factorio-layout",
|
"factorio-layout",
|
||||||
"factorio-pathfinding",
|
"factorio-pathfinding",
|
||||||
"rand",
|
"rand",
|
||||||
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"serde_yaml",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@ factorio-pathfinding = { path = "../factorio-pathfinding" }
|
||||||
factorio-layout = { path = "../factorio-layout" }
|
factorio-layout = { path = "../factorio-layout" }
|
||||||
factorio-core = { path = "../factorio-core" }
|
factorio-core = { path = "../factorio-core" }
|
||||||
factorio-blueprint = { path = "../factorio-blueprint" }
|
factorio-blueprint = { path = "../factorio-blueprint" }
|
||||||
|
serde = { version = "1.0.192", features = ["derive"] }
|
||||||
serde_json = "1.0.135"
|
serde_json = "1.0.135"
|
||||||
|
serde_yaml = "0.9.34"
|
||||||
clap = { version = "4.5.26", features = ["derive"] }
|
clap = { version = "4.5.26", features = ["derive"] }
|
||||||
rand = { version = "0.8.5", features = ["small_rng"] }
|
rand = { version = "0.8.5", features = ["small_rng"] }
|
||||||
|
|
|
||||||
43
factorio-blueprint-generator/factory_graph_fast_inserter.yml
Normal file
43
factorio-blueprint-generator/factory_graph_fast_inserter.yml
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
subfactories:
|
||||||
|
- !SubFactory
|
||||||
|
recipe: iron-gear-wheel
|
||||||
|
machines: 2
|
||||||
|
machine: assembly-machine-3
|
||||||
|
- !SubFactory
|
||||||
|
recipe: copper-cable
|
||||||
|
machines: 9
|
||||||
|
machine: assembly-machine-3
|
||||||
|
- !SubFactory
|
||||||
|
recipe: electronic-circuit
|
||||||
|
machines: 6
|
||||||
|
machine: assembly-machine-3
|
||||||
|
- !BeltPool
|
||||||
|
- !SubFactory
|
||||||
|
recipe: inserter
|
||||||
|
machines: 2
|
||||||
|
machine: assembly-machine-3
|
||||||
|
- !SubFactory
|
||||||
|
recipe: fast-inserter
|
||||||
|
machines: 2
|
||||||
|
machine: assembly-machine-3
|
||||||
|
factory_connections:
|
||||||
|
- item: iron-gear-wheel
|
||||||
|
amount: 5
|
||||||
|
from: 0
|
||||||
|
to: 4
|
||||||
|
- item: copper-cable
|
||||||
|
amount: 45
|
||||||
|
from: 1
|
||||||
|
to: 2
|
||||||
|
- item: electronic-circuit
|
||||||
|
amount: 15
|
||||||
|
from: 2
|
||||||
|
to: 3
|
||||||
|
- item: electronic-circuit
|
||||||
|
amount: 5
|
||||||
|
from: 3
|
||||||
|
to: 4
|
||||||
|
- item: electronic-circuit
|
||||||
|
amount: 10
|
||||||
|
from: 3
|
||||||
|
to: 5
|
||||||
49
factorio-blueprint-generator/factory_graph_inserter.yml
Normal file
49
factorio-blueprint-generator/factory_graph_inserter.yml
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
subfactories:
|
||||||
|
- !SubFactory
|
||||||
|
recipe: iron-gear-wheel
|
||||||
|
machines: 2
|
||||||
|
machine: assembly-machine-3
|
||||||
|
- !SubFactory
|
||||||
|
recipe: copper-cable
|
||||||
|
machines: 3
|
||||||
|
machine: assembly-machine-3
|
||||||
|
- !SubFactory
|
||||||
|
recipe: electronic-circuit
|
||||||
|
machines: 2
|
||||||
|
machine: assembly-machine-3
|
||||||
|
- !SubFactory
|
||||||
|
recipe: inserter
|
||||||
|
machines: 2
|
||||||
|
machine: assembly-machine-3
|
||||||
|
- !ExternalConnection
|
||||||
|
inputs: 1
|
||||||
|
outputs: 5
|
||||||
|
factory_connections:
|
||||||
|
- item: iron-gear-wheel
|
||||||
|
amount: 5
|
||||||
|
from: 0
|
||||||
|
to: 3
|
||||||
|
- item: copper-cable
|
||||||
|
amount: 15
|
||||||
|
from: 1
|
||||||
|
to: 2
|
||||||
|
- item: electronic-circuit
|
||||||
|
amount: 5
|
||||||
|
from: 2
|
||||||
|
to: 3
|
||||||
|
- item: iron-plate
|
||||||
|
amount: 10
|
||||||
|
from: 4
|
||||||
|
to: 0
|
||||||
|
- item: iron-plate
|
||||||
|
amount: 5
|
||||||
|
from: 4
|
||||||
|
to: 2
|
||||||
|
- item: copper-plate
|
||||||
|
amount: 7.5
|
||||||
|
from: 4
|
||||||
|
to: 1
|
||||||
|
- item: inserter
|
||||||
|
amount: 5
|
||||||
|
from: 3
|
||||||
|
to: 4
|
||||||
|
|
@ -214,3 +214,385 @@ pub fn assembly_line(assembly_machines: usize, recipe: impl AsRef<str>) -> Bluep
|
||||||
|
|
||||||
blueprint
|
blueprint
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn assembly_line_2_input(
|
||||||
|
assembly_machines: usize,
|
||||||
|
recipe: impl AsRef<str>,
|
||||||
|
input_belt1: Beltspeed,
|
||||||
|
input_belt2: Option<Beltspeed>,
|
||||||
|
output_belt: Beltspeed,
|
||||||
|
) -> (Blueprint, Position, PositionType, Vec<PositionType>) {
|
||||||
|
let halve_machines = assembly_machines / 2;
|
||||||
|
let mut blueprint = Blueprint::new();
|
||||||
|
|
||||||
|
let mut last = None;
|
||||||
|
for i in (0..halve_machines.div_ceil(3)).rev() {
|
||||||
|
let y_pos = if i == halve_machines.div_ceil(3) - 1 && halve_machines % 3 == 1 {
|
||||||
|
1 + 18 * i as PositionType
|
||||||
|
} else {
|
||||||
|
9 + 18 * i as PositionType
|
||||||
|
};
|
||||||
|
let top = blueprint.add_entity(Entity::new_electric_pole(
|
||||||
|
ElectricPoleType::Medium,
|
||||||
|
Position::new(y_pos, 5),
|
||||||
|
));
|
||||||
|
|
||||||
|
let middle = blueprint.add_entity(Entity::new_electric_pole(
|
||||||
|
ElectricPoleType::Medium,
|
||||||
|
Position::new(y_pos, 17),
|
||||||
|
));
|
||||||
|
|
||||||
|
let bottom = blueprint.add_entity(Entity::new_electric_pole(
|
||||||
|
ElectricPoleType::Medium,
|
||||||
|
Position::new(y_pos, 25),
|
||||||
|
));
|
||||||
|
|
||||||
|
blueprint.add_wire(top, 5, middle, 5);
|
||||||
|
blueprint.add_wire(middle, 5, bottom, 5);
|
||||||
|
if let Some((last_top, last_middle, last_bottom)) = last {
|
||||||
|
blueprint.add_wire(top, 5, last_top, 5);
|
||||||
|
blueprint.add_wire(middle, 5, last_middle, 5);
|
||||||
|
blueprint.add_wire(bottom, 5, last_bottom, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
last = Some((top, middle, bottom));
|
||||||
|
}
|
||||||
|
|
||||||
|
for i in 0..halve_machines {
|
||||||
|
blueprint.add_entity(Entity::new_production(
|
||||||
|
"assembling-machine-3",
|
||||||
|
recipe.as_ref(),
|
||||||
|
Position::new(3 + 6 * i as PositionType, 9),
|
||||||
|
Direction::Up,
|
||||||
|
Position::new(6, 6),
|
||||||
|
));
|
||||||
|
blueprint.add_entity(Entity::new_production(
|
||||||
|
"assembling-machine-3",
|
||||||
|
recipe.as_ref(),
|
||||||
|
Position::new(3 + 6 * i as PositionType, 21),
|
||||||
|
Direction::Up,
|
||||||
|
Position::new(6, 6),
|
||||||
|
));
|
||||||
|
match i % 3 {
|
||||||
|
0 => {
|
||||||
|
if input_belt2.is_some() {
|
||||||
|
blueprint.add_entity(Entity::new_inserter(
|
||||||
|
InserterType::Long,
|
||||||
|
None,
|
||||||
|
Position::new(3 + 6 * i as PositionType, 5),
|
||||||
|
Direction::Up,
|
||||||
|
));
|
||||||
|
blueprint.add_entity(Entity::new_inserter(
|
||||||
|
InserterType::Long,
|
||||||
|
None,
|
||||||
|
Position::new(3 + 6 * i as PositionType, 25),
|
||||||
|
Direction::Down,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
blueprint.add_entity(Entity::new_inserter(
|
||||||
|
InserterType::Fast,
|
||||||
|
None,
|
||||||
|
Position::new(5 + 6 * i as PositionType, 5),
|
||||||
|
Direction::Up,
|
||||||
|
));
|
||||||
|
blueprint.add_entity(Entity::new_inserter(
|
||||||
|
InserterType::Fast,
|
||||||
|
None,
|
||||||
|
Position::new(3 + 6 * i as PositionType, 13),
|
||||||
|
Direction::Up,
|
||||||
|
));
|
||||||
|
blueprint.add_entity(Entity::new_inserter(
|
||||||
|
InserterType::Fast,
|
||||||
|
None,
|
||||||
|
Position::new(3 + 6 * i as PositionType, 17),
|
||||||
|
Direction::Down,
|
||||||
|
));
|
||||||
|
blueprint.add_entity(Entity::new_inserter(
|
||||||
|
InserterType::Fast,
|
||||||
|
None,
|
||||||
|
Position::new(5 + 6 * i as PositionType, 25),
|
||||||
|
Direction::Down,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
1 => {
|
||||||
|
if input_belt2.is_some() {
|
||||||
|
blueprint.add_entity(Entity::new_inserter(
|
||||||
|
InserterType::Long,
|
||||||
|
None,
|
||||||
|
Position::new(1 + 6 * i as PositionType, 5),
|
||||||
|
Direction::Up,
|
||||||
|
));
|
||||||
|
blueprint.add_entity(Entity::new_inserter(
|
||||||
|
InserterType::Long,
|
||||||
|
None,
|
||||||
|
Position::new(1 + 6 * i as PositionType, 25),
|
||||||
|
Direction::Down,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
blueprint.add_entity(Entity::new_inserter(
|
||||||
|
InserterType::Fast,
|
||||||
|
None,
|
||||||
|
Position::new(5 + 6 * i as PositionType, 5),
|
||||||
|
Direction::Up,
|
||||||
|
));
|
||||||
|
blueprint.add_entity(Entity::new_inserter(
|
||||||
|
InserterType::Fast,
|
||||||
|
None,
|
||||||
|
Position::new(1 + 6 * i as PositionType, 13),
|
||||||
|
Direction::Up,
|
||||||
|
));
|
||||||
|
blueprint.add_entity(Entity::new_inserter(
|
||||||
|
InserterType::Fast,
|
||||||
|
None,
|
||||||
|
Position::new(1 + 6 * i as PositionType, 17),
|
||||||
|
Direction::Down,
|
||||||
|
));
|
||||||
|
blueprint.add_entity(Entity::new_inserter(
|
||||||
|
InserterType::Fast,
|
||||||
|
None,
|
||||||
|
Position::new(5 + 6 * i as PositionType, 25),
|
||||||
|
Direction::Down,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
2 => {
|
||||||
|
if input_belt2.is_some() {
|
||||||
|
blueprint.add_entity(Entity::new_inserter(
|
||||||
|
InserterType::Long,
|
||||||
|
None,
|
||||||
|
Position::new(1 + 6 * i as PositionType, 5),
|
||||||
|
Direction::Up,
|
||||||
|
));
|
||||||
|
blueprint.add_entity(Entity::new_inserter(
|
||||||
|
InserterType::Long,
|
||||||
|
None,
|
||||||
|
Position::new(1 + 6 * i as PositionType, 25),
|
||||||
|
Direction::Down,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
blueprint.add_entity(Entity::new_inserter(
|
||||||
|
InserterType::Fast,
|
||||||
|
None,
|
||||||
|
Position::new(3 + 6 * i as PositionType, 5),
|
||||||
|
Direction::Up,
|
||||||
|
));
|
||||||
|
blueprint.add_entity(Entity::new_inserter(
|
||||||
|
InserterType::Fast,
|
||||||
|
None,
|
||||||
|
Position::new(1 + 6 * i as PositionType, 13),
|
||||||
|
Direction::Up,
|
||||||
|
));
|
||||||
|
blueprint.add_entity(Entity::new_inserter(
|
||||||
|
InserterType::Fast,
|
||||||
|
None,
|
||||||
|
Position::new(1 + 6 * i as PositionType, 17),
|
||||||
|
Direction::Down,
|
||||||
|
));
|
||||||
|
blueprint.add_entity(Entity::new_inserter(
|
||||||
|
InserterType::Fast,
|
||||||
|
None,
|
||||||
|
Position::new(3 + 6 * i as PositionType, 25),
|
||||||
|
Direction::Down,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for i in 0..(3 * halve_machines + 2) {
|
||||||
|
if let Some(beltspeed) = input_belt2 {
|
||||||
|
if i > 0 {
|
||||||
|
blueprint.add_entity(Entity::new_belt(
|
||||||
|
beltspeed,
|
||||||
|
Position::new(1 + 2 * i as PositionType, 1),
|
||||||
|
Direction::Left,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if i < (3 * halve_machines) {
|
||||||
|
blueprint.add_entity(Entity::new_belt(
|
||||||
|
input_belt1,
|
||||||
|
Position::new(1 + 2 * i as PositionType, 3),
|
||||||
|
Direction::Right,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
if i < (3 * halve_machines - 1) {
|
||||||
|
blueprint.add_entity(Entity::new_belt(
|
||||||
|
output_belt,
|
||||||
|
Position::new(1 + 2 * i as PositionType, 15),
|
||||||
|
Direction::Left,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
if i > 1 && i < (3 * halve_machines + 1) {
|
||||||
|
blueprint.add_entity(Entity::new_belt(
|
||||||
|
input_belt1,
|
||||||
|
Position::new(1 + 2 * i as PositionType, 27),
|
||||||
|
Direction::Left,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
if let Some(beltspeed) = input_belt2 {
|
||||||
|
if i < (3 * halve_machines + 1) {
|
||||||
|
blueprint.add_entity(Entity::new_belt(
|
||||||
|
beltspeed,
|
||||||
|
Position::new(1 + 2 * i as PositionType, 29),
|
||||||
|
Direction::Right,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for i in 0..15 {
|
||||||
|
if i > 0 && i < 13 {
|
||||||
|
blueprint.add_entity(Entity::new_belt(
|
||||||
|
input_belt1,
|
||||||
|
Position::new(
|
||||||
|
1 + 6 * halve_machines as PositionType,
|
||||||
|
1 + 2 * i as PositionType,
|
||||||
|
),
|
||||||
|
Direction::Down,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
if let Some(beltspeed) = input_belt2 {
|
||||||
|
if i > 0 {
|
||||||
|
blueprint.add_entity(Entity::new_belt(
|
||||||
|
beltspeed,
|
||||||
|
Position::new(
|
||||||
|
3 + 6 * halve_machines as PositionType,
|
||||||
|
1 + 2 * i as PositionType,
|
||||||
|
),
|
||||||
|
Direction::Up,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if assembly_machines % 2 == 1 {
|
||||||
|
let middle = blueprint.add_entity(Entity::new_electric_pole(
|
||||||
|
ElectricPoleType::Medium,
|
||||||
|
Position::new(-3, 17),
|
||||||
|
));
|
||||||
|
|
||||||
|
let bottom = blueprint.add_entity(Entity::new_electric_pole(
|
||||||
|
ElectricPoleType::Medium,
|
||||||
|
Position::new(-3, 25),
|
||||||
|
));
|
||||||
|
|
||||||
|
blueprint.add_wire(middle, 5, bottom, 5);
|
||||||
|
|
||||||
|
if let Some((_, last_middle, last_bottom)) = last {
|
||||||
|
blueprint.add_wire(middle, 5, last_middle, 5);
|
||||||
|
blueprint.add_wire(bottom, 5, last_bottom, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
blueprint.add_entity(Entity::new_production(
|
||||||
|
"assembling-machine-3",
|
||||||
|
recipe.as_ref(),
|
||||||
|
Position::new(-3, 21),
|
||||||
|
Direction::Up,
|
||||||
|
Position::new(6, 6),
|
||||||
|
));
|
||||||
|
|
||||||
|
blueprint.add_entity(Entity::new_inserter(
|
||||||
|
InserterType::Fast,
|
||||||
|
None,
|
||||||
|
Position::new(-5, 17),
|
||||||
|
Direction::Down,
|
||||||
|
));
|
||||||
|
blueprint.add_entity(Entity::new_inserter(
|
||||||
|
InserterType::Long,
|
||||||
|
None,
|
||||||
|
Position::new(-1, 17),
|
||||||
|
Direction::Down,
|
||||||
|
));
|
||||||
|
blueprint.add_entity(Entity::new_inserter(
|
||||||
|
InserterType::Fast,
|
||||||
|
None,
|
||||||
|
Position::new(-1, 25),
|
||||||
|
Direction::Down,
|
||||||
|
));
|
||||||
|
if input_belt2.is_some() {
|
||||||
|
blueprint.add_entity(Entity::new_inserter(
|
||||||
|
InserterType::Long,
|
||||||
|
None,
|
||||||
|
Position::new(-5, 25),
|
||||||
|
Direction::Down,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
blueprint.add_entity(Entity::new_belt(
|
||||||
|
output_belt,
|
||||||
|
Position::new(-1, 13),
|
||||||
|
Direction::Down,
|
||||||
|
));
|
||||||
|
blueprint.add_entity(Entity::new_belt(
|
||||||
|
output_belt,
|
||||||
|
Position::new(-1, 15),
|
||||||
|
Direction::Left,
|
||||||
|
));
|
||||||
|
blueprint.add_entity(Entity::new_belt(
|
||||||
|
output_belt,
|
||||||
|
Position::new(-3, 13),
|
||||||
|
Direction::Left,
|
||||||
|
));
|
||||||
|
blueprint.add_entity(Entity::new_belt(
|
||||||
|
output_belt,
|
||||||
|
Position::new(-3, 15),
|
||||||
|
Direction::Up,
|
||||||
|
));
|
||||||
|
blueprint.add_entity(Entity::new_belt(
|
||||||
|
output_belt,
|
||||||
|
Position::new(-5, 13),
|
||||||
|
Direction::Left,
|
||||||
|
));
|
||||||
|
blueprint.add_entity(Entity::new_belt(
|
||||||
|
output_belt,
|
||||||
|
Position::new(-5, 15),
|
||||||
|
Direction::Up,
|
||||||
|
));
|
||||||
|
|
||||||
|
for i in 0..3 {
|
||||||
|
blueprint.add_entity(Entity::new_belt(
|
||||||
|
input_belt1,
|
||||||
|
Position::new(-5 + 2 * i as PositionType, 3),
|
||||||
|
Direction::Right,
|
||||||
|
));
|
||||||
|
blueprint.add_entity(Entity::new_belt(
|
||||||
|
input_belt1,
|
||||||
|
Position::new(-1 + 2 * i as PositionType, 27),
|
||||||
|
Direction::Left,
|
||||||
|
));
|
||||||
|
if let Some(beltspeed) = input_belt2 {
|
||||||
|
blueprint.add_entity(Entity::new_belt(
|
||||||
|
beltspeed,
|
||||||
|
Position::new(-5 + 2 * i as PositionType, 29),
|
||||||
|
Direction::Right,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
blueprint.transform(Transformation::new(Direction::Up, Position::new(6, 0)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if input_belt2.is_none() {
|
||||||
|
blueprint.transform(Transformation::new(Direction::Up, Position::new(0, -2)));
|
||||||
|
}
|
||||||
|
|
||||||
|
(
|
||||||
|
blueprint,
|
||||||
|
Position::new(
|
||||||
|
3 * assembly_machines.div_ceil(2) as PositionType
|
||||||
|
+ if input_belt2.is_some() { 2 } else { 1 },
|
||||||
|
if input_belt2.is_some() { 15 } else { 13 },
|
||||||
|
),
|
||||||
|
match (input_belt2.is_some(), assembly_machines % 2 == 0) {
|
||||||
|
(true, true) => 7,
|
||||||
|
(true, false) => 6,
|
||||||
|
(false, true) => 6,
|
||||||
|
(false, false) => 5,
|
||||||
|
},
|
||||||
|
if input_belt2.is_some() {
|
||||||
|
vec![1, 14]
|
||||||
|
} else {
|
||||||
|
vec![0]
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use factorio_blueprint::{BlueprintString, encode};
|
use factorio_blueprint::{BlueprintString, encode};
|
||||||
use factorio_blueprint_generator::assembly::assembly_line;
|
use factorio_blueprint_generator::assembly::{assembly_line, assembly_line_2_input};
|
||||||
|
use factorio_core::beltoptions::Beltspeed;
|
||||||
|
|
||||||
#[derive(Parser)]
|
#[derive(Parser)]
|
||||||
struct Args {
|
struct Args {
|
||||||
|
|
@ -8,12 +9,22 @@ struct Args {
|
||||||
json: bool,
|
json: bool,
|
||||||
assembly_machines: usize,
|
assembly_machines: usize,
|
||||||
recipe: String,
|
recipe: String,
|
||||||
|
output_belt: Beltspeed,
|
||||||
|
input_belt: Vec<Beltspeed>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let args = Args::parse();
|
let args = Args::parse();
|
||||||
let b = BlueprintString::Blueprint(
|
let b = BlueprintString::Blueprint(
|
||||||
assembly_line(args.assembly_machines, args.recipe).to_blueprint(),
|
assembly_line_2_input(
|
||||||
|
args.assembly_machines,
|
||||||
|
args.recipe,
|
||||||
|
args.input_belt[0],
|
||||||
|
args.input_belt.get(1).copied(),
|
||||||
|
args.output_belt,
|
||||||
|
)
|
||||||
|
.0
|
||||||
|
.to_blueprint(),
|
||||||
);
|
);
|
||||||
|
|
||||||
if args.json {
|
if args.json {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use factorio_blueprint::{BlueprintString, encode};
|
use factorio_blueprint::{BlueprintString, encode};
|
||||||
use factorio_blueprint_generator::factory::generate_factory;
|
use factorio_blueprint_generator::factory::{FactoryGraph, generate_factory};
|
||||||
use factorio_core::prelude::*;
|
use factorio_core::prelude::*;
|
||||||
use factorio_layout::{genetic_algorithm_v1::GeneticAlgorithm, valid_layout::ValidLayout};
|
use factorio_layout::{genetic_algorithm_v1::GeneticAlgorithm, valid_layout::ValidLayout};
|
||||||
use factorio_pathfinding::belt_finding::ConflictAvoidance;
|
use factorio_pathfinding::belt_finding::ConflictAvoidance;
|
||||||
|
|
@ -12,11 +14,18 @@ struct Args {
|
||||||
seed: u64,
|
seed: u64,
|
||||||
#[arg(short, long)]
|
#[arg(short, long)]
|
||||||
json: bool,
|
json: bool,
|
||||||
|
|
||||||
|
path: PathBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let args = Args::parse();
|
let args = Args::parse();
|
||||||
|
|
||||||
|
let text = std::fs::File::open(&args.path).unwrap();
|
||||||
|
let factory_graph: FactoryGraph = serde_yaml::from_reader(text).unwrap();
|
||||||
|
|
||||||
|
dbg!(&factory_graph);
|
||||||
|
|
||||||
let l = ValidLayout {
|
let l = ValidLayout {
|
||||||
max_tries: 10,
|
max_tries: 10,
|
||||||
retries: 20,
|
retries: 20,
|
||||||
|
|
@ -38,7 +47,9 @@ fn main() {
|
||||||
|
|
||||||
let mut rng = SmallRng::seed_from_u64(args.seed);
|
let mut rng = SmallRng::seed_from_u64(args.seed);
|
||||||
|
|
||||||
let b = BlueprintString::Blueprint(generate_factory(&l, &p, &mut rng).to_blueprint());
|
let b = BlueprintString::Blueprint(
|
||||||
|
generate_factory(&l, &p, factory_graph, &mut rng).to_blueprint(),
|
||||||
|
);
|
||||||
|
|
||||||
if args.json {
|
if args.json {
|
||||||
println!("{}", serde_json::to_string_pretty(&b).unwrap());
|
println!("{}", serde_json::to_string_pretty(&b).unwrap());
|
||||||
|
|
|
||||||
|
|
@ -3,85 +3,124 @@ use factorio_core::{beltoptions::Beltspeed, prelude::*};
|
||||||
use factorio_layout::{Connection, Interface, LayoutInput, Layouter, MacroBlock};
|
use factorio_layout::{Connection, Interface, LayoutInput, Layouter, MacroBlock};
|
||||||
use factorio_pathfinding::Pathfinder;
|
use factorio_pathfinding::Pathfinder;
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::assembly::assembly_line;
|
use crate::assembly::{assembly_line, assembly_line_2_input};
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
|
pub struct FactoryGraph {
|
||||||
|
pub subfactories: Vec<Building>,
|
||||||
|
pub factory_connections: Vec<FactoryConnection>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
|
pub enum Building {
|
||||||
|
SubFactory {
|
||||||
|
recipe: String,
|
||||||
|
machines: usize,
|
||||||
|
machine: String,
|
||||||
|
},
|
||||||
|
ExternalConnection {
|
||||||
|
inputs: usize,
|
||||||
|
outputs: usize,
|
||||||
|
},
|
||||||
|
BeltPool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
|
pub struct FactoryConnection {
|
||||||
|
pub item: String,
|
||||||
|
pub amount: f64,
|
||||||
|
pub from: usize,
|
||||||
|
pub to: usize,
|
||||||
|
}
|
||||||
|
|
||||||
pub fn generate_factory<L: Layouter, P: Pathfinder>(
|
pub fn generate_factory<L: Layouter, P: Pathfinder>(
|
||||||
layouter: &L,
|
layouter: &L,
|
||||||
pathfinder: &P,
|
pathfinder: &P,
|
||||||
|
factory_graph: FactoryGraph,
|
||||||
rng: &mut impl Rng,
|
rng: &mut impl Rng,
|
||||||
) -> Blueprint {
|
) -> Blueprint {
|
||||||
// 2 * gears
|
let mut blocks = Vec::new();
|
||||||
// 3 * copper wires
|
let mut blueprints = Vec::new();
|
||||||
// 2 * green circuits
|
let mut connections = Vec::new();
|
||||||
// 2 * inserter
|
let mut used_connections = Vec::new();
|
||||||
let input = vec![
|
|
||||||
Interface {
|
|
||||||
offset: Position::new(0, 1),
|
|
||||||
dir: Direction::Right,
|
|
||||||
},
|
|
||||||
Interface {
|
|
||||||
offset: Position::new(0, 7),
|
|
||||||
dir: Direction::Right,
|
|
||||||
},
|
|
||||||
Interface {
|
|
||||||
offset: Position::new(0, 8),
|
|
||||||
dir: Direction::Right,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
let output = vec![Interface {
|
|
||||||
offset: Position::new(0, 0),
|
|
||||||
dir: Direction::Left,
|
|
||||||
}];
|
|
||||||
let blocks = vec![
|
|
||||||
MacroBlock {
|
|
||||||
size: Position::new(6, 9),
|
|
||||||
input: input.clone(),
|
|
||||||
output: output.clone(),
|
|
||||||
},
|
|
||||||
MacroBlock {
|
|
||||||
size: Position::new(9, 9),
|
|
||||||
input: input.clone(),
|
|
||||||
output: output.clone(),
|
|
||||||
},
|
|
||||||
MacroBlock {
|
|
||||||
size: Position::new(6, 9),
|
|
||||||
input: input.clone(),
|
|
||||||
output: output.clone(),
|
|
||||||
},
|
|
||||||
MacroBlock {
|
|
||||||
size: Position::new(6, 9),
|
|
||||||
input: input.clone(),
|
|
||||||
output: output.clone(),
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
let connections = vec![
|
for b in &factory_graph.subfactories {
|
||||||
Connection {
|
match b {
|
||||||
startblock: 0,
|
Building::SubFactory {
|
||||||
startpoint: 0,
|
recipe,
|
||||||
endblock: 3,
|
machines,
|
||||||
endpoint: 0,
|
machine,
|
||||||
|
} => {
|
||||||
|
assert!(machine == "assembly-machine-3");
|
||||||
|
|
||||||
|
let (b, size, y_output, y_inputs) = assembly_line_2_input(
|
||||||
|
*machines,
|
||||||
|
recipe,
|
||||||
|
Beltspeed::Normal,
|
||||||
|
Some(Beltspeed::Normal),
|
||||||
|
Beltspeed::Normal,
|
||||||
|
);
|
||||||
|
|
||||||
|
blueprints.push(b);
|
||||||
|
blocks.push(MacroBlock {
|
||||||
|
size,
|
||||||
|
input: y_inputs
|
||||||
|
.iter()
|
||||||
|
.map(|&y| Interface {
|
||||||
|
offset: Position::new(0, y),
|
||||||
|
dir: Direction::Right,
|
||||||
|
})
|
||||||
|
.collect(),
|
||||||
|
output: vec![Interface {
|
||||||
|
offset: Position::new(0, y_output),
|
||||||
|
dir: Direction::Left,
|
||||||
|
}],
|
||||||
|
});
|
||||||
|
|
||||||
|
used_connections.push((0, 0));
|
||||||
|
}
|
||||||
|
Building::ExternalConnection { inputs, outputs } => {
|
||||||
|
blocks.push(MacroBlock {
|
||||||
|
size: Position::new(1, (inputs + outputs) as PositionType),
|
||||||
|
input: (0..*inputs)
|
||||||
|
.map(|y| Interface {
|
||||||
|
offset: Position::new(0, y as PositionType),
|
||||||
|
dir: Direction::Left,
|
||||||
|
})
|
||||||
|
.collect(),
|
||||||
|
output: (0..*outputs)
|
||||||
|
.map(|y| Interface {
|
||||||
|
offset: Position::new(0, (inputs + y) as PositionType),
|
||||||
|
dir: Direction::Right,
|
||||||
|
})
|
||||||
|
.collect(),
|
||||||
|
});
|
||||||
|
|
||||||
|
blueprints.push(Blueprint::new());
|
||||||
|
used_connections.push((0, 0));
|
||||||
|
}
|
||||||
|
Building::BeltPool => todo!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for c in &factory_graph.factory_connections {
|
||||||
|
connections.push(Connection {
|
||||||
|
startblock: c.from,
|
||||||
|
startpoint: used_connections[c.from].0,
|
||||||
|
endblock: c.to,
|
||||||
|
endpoint: used_connections[c.to].1,
|
||||||
lanes: 1,
|
lanes: 1,
|
||||||
beltspeed: Beltspeed::Fast,
|
beltspeed: Beltspeed::Normal,
|
||||||
},
|
});
|
||||||
Connection {
|
|
||||||
startblock: 1,
|
used_connections[c.from].0 += 1;
|
||||||
startpoint: 0,
|
used_connections[c.to].1 += 1;
|
||||||
endblock: 2,
|
}
|
||||||
endpoint: 0,
|
|
||||||
lanes: 1,
|
// dbg!(&blocks);
|
||||||
beltspeed: Beltspeed::Fast,
|
// dbg!(&connections);
|
||||||
},
|
|
||||||
Connection {
|
|
||||||
startblock: 2,
|
|
||||||
startpoint: 0,
|
|
||||||
endblock: 3,
|
|
||||||
endpoint: 1,
|
|
||||||
lanes: 1,
|
|
||||||
beltspeed: Beltspeed::Fast,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
let l = layouter
|
let l = layouter
|
||||||
.layout(
|
.layout(
|
||||||
|
|
@ -94,13 +133,6 @@ pub fn generate_factory<L: Layouter, P: Pathfinder>(
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let blueprints = vec![
|
|
||||||
assembly_line(2, "iron-gear-wheel"),
|
|
||||||
assembly_line(3, "copper-cable"),
|
|
||||||
assembly_line(2, "electronic-circuit"),
|
|
||||||
assembly_line(2, "inserter"),
|
|
||||||
];
|
|
||||||
|
|
||||||
let mut b = Blueprint::new();
|
let mut b = Blueprint::new();
|
||||||
for (block, mut assembly_blueprint) in l.positions.iter().zip(blueprints) {
|
for (block, mut assembly_blueprint) in l.positions.iter().zip(blueprints) {
|
||||||
let offset = match block.dir() {
|
let offset = match block.dir() {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue