Improve factory generation
This commit is contained in:
parent
0f8bf5000c
commit
ec869d4c18
7 changed files with 107 additions and 46 deletions
|
|
@ -1,49 +1,58 @@
|
||||||
subfactories:
|
subfactories:
|
||||||
- !SubFactory
|
- !SubFactory
|
||||||
recipe: iron-gear-wheel
|
recipe: iron-gear-wheel
|
||||||
machines: 2
|
machines: 6
|
||||||
machine: assembly-machine-3
|
machine: assembly-machine-3
|
||||||
- !SubFactory
|
- !SubFactory
|
||||||
recipe: copper-cable
|
recipe: copper-cable
|
||||||
machines: 3
|
machines: 9
|
||||||
machine: assembly-machine-3
|
machine: assembly-machine-3
|
||||||
- !SubFactory
|
- !SubFactory
|
||||||
recipe: electronic-circuit
|
recipe: electronic-circuit
|
||||||
machines: 2
|
machines: 6
|
||||||
machine: assembly-machine-3
|
machine: assembly-machine-3
|
||||||
- !SubFactory
|
- !SubFactory
|
||||||
recipe: inserter
|
recipe: inserter
|
||||||
machines: 2
|
machines: 6
|
||||||
machine: assembly-machine-3
|
machine: assembly-machine-3
|
||||||
- !ExternalConnection
|
- !ExternalConnection
|
||||||
inputs: 1
|
inputs: 1
|
||||||
outputs: 5
|
outputs: 5
|
||||||
|
- !SideLoader
|
||||||
factory_connections:
|
factory_connections:
|
||||||
- item: iron-gear-wheel
|
- item: iron-gear-wheel
|
||||||
amount: 5
|
|
||||||
from: 0
|
|
||||||
to: 3
|
|
||||||
- item: copper-cable
|
|
||||||
amount: 15
|
amount: 15
|
||||||
|
from: 0
|
||||||
|
to: 5
|
||||||
|
- item: copper-cable
|
||||||
|
amount: 45
|
||||||
from: 1
|
from: 1
|
||||||
to: 2
|
to: 2
|
||||||
- item: electronic-circuit
|
|
||||||
amount: 5
|
|
||||||
from: 2
|
|
||||||
to: 3
|
|
||||||
- item: iron-plate
|
- item: iron-plate
|
||||||
amount: 10
|
amount: 30
|
||||||
from: 4
|
from: 4
|
||||||
to: 0
|
to: 0
|
||||||
- item: iron-plate
|
- item: iron-plate
|
||||||
amount: 5
|
amount: 15
|
||||||
from: 4
|
from: 4
|
||||||
to: 2
|
to: 2
|
||||||
- item: copper-plate
|
- item: copper-plate
|
||||||
amount: 7.5
|
amount: 22.5
|
||||||
from: 4
|
from: 4
|
||||||
to: 1
|
to: 1
|
||||||
- item: inserter
|
- item: inserter
|
||||||
amount: 5
|
amount: 15
|
||||||
from: 3
|
from: 3
|
||||||
to: 4
|
to: 4
|
||||||
|
- 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
|
||||||
|
from: 2
|
||||||
|
to: 3
|
||||||
|
|
|
||||||
|
|
@ -415,7 +415,8 @@ pub fn assembly_line_2_input(
|
||||||
Direction::Right,
|
Direction::Right,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
if i < (3 * halve_machines - 1) {
|
if i < (3 * halve_machines - 2) || (halve_machines % 3 == 1 && i < (3 * halve_machines - 1))
|
||||||
|
{
|
||||||
blueprint.add_entity(Entity::new_belt(
|
blueprint.add_entity(Entity::new_belt(
|
||||||
output_belt,
|
output_belt,
|
||||||
Position::new(1 + 2 * i as PositionType, 15),
|
Position::new(1 + 2 * i as PositionType, 15),
|
||||||
|
|
|
||||||
|
|
@ -29,16 +29,16 @@ fn main() {
|
||||||
let l = ValidLayout {
|
let l = ValidLayout {
|
||||||
max_tries: 10,
|
max_tries: 10,
|
||||||
retries: 20,
|
retries: 20,
|
||||||
start_size: Position::new(20, 20),
|
start_size: Position::new(48, 48),
|
||||||
growth: Position::new(5, 5),
|
growth: Position::new(0, 0),
|
||||||
};
|
};
|
||||||
|
|
||||||
let l = GeneticAlgorithm {
|
let l = GeneticAlgorithm {
|
||||||
mutation_retries: 20,
|
mutation_retries: 20,
|
||||||
population_size: 10,
|
population_size: 20,
|
||||||
population_keep: 2,
|
population_keep: 1,
|
||||||
population_new: 2,
|
population_new: 2,
|
||||||
generations: 20,
|
generations: 50,
|
||||||
valid_layout: l,
|
valid_layout: l,
|
||||||
};
|
};
|
||||||
let p = ConflictAvoidance {
|
let p = ConflictAvoidance {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use factorio_blueprint::abstraction::Blueprint;
|
use factorio_blueprint::abstraction::{Blueprint, Entity};
|
||||||
use factorio_core::{beltoptions::Beltspeed, prelude::*};
|
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;
|
||||||
|
|
@ -25,6 +25,7 @@ pub enum Building {
|
||||||
outputs: usize,
|
outputs: usize,
|
||||||
},
|
},
|
||||||
BeltPool,
|
BeltPool,
|
||||||
|
SideLoader,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
|
|
@ -46,7 +47,7 @@ pub fn generate_factory<L: Layouter, P: Pathfinder>(
|
||||||
let mut connections = Vec::new();
|
let mut connections = Vec::new();
|
||||||
let mut used_connections = Vec::new();
|
let mut used_connections = Vec::new();
|
||||||
|
|
||||||
for b in &factory_graph.subfactories {
|
for (i, b) in factory_graph.subfactories.iter().enumerate() {
|
||||||
match b {
|
match b {
|
||||||
Building::SubFactory {
|
Building::SubFactory {
|
||||||
recipe,
|
recipe,
|
||||||
|
|
@ -55,12 +56,22 @@ pub fn generate_factory<L: Layouter, P: Pathfinder>(
|
||||||
} => {
|
} => {
|
||||||
assert!(machine == "assembly-machine-3");
|
assert!(machine == "assembly-machine-3");
|
||||||
|
|
||||||
|
let input_count = factory_graph
|
||||||
|
.factory_connections
|
||||||
|
.iter()
|
||||||
|
.filter(|&c| c.to == i)
|
||||||
|
.count();
|
||||||
|
|
||||||
let (b, size, y_output, y_inputs) = assembly_line_2_input(
|
let (b, size, y_output, y_inputs) = assembly_line_2_input(
|
||||||
*machines,
|
*machines,
|
||||||
recipe,
|
recipe,
|
||||||
Beltspeed::Normal,
|
Beltspeed::Express,
|
||||||
Some(Beltspeed::Normal),
|
if input_count == 2 {
|
||||||
Beltspeed::Normal,
|
Some(Beltspeed::Express)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
|
Beltspeed::Express,
|
||||||
);
|
);
|
||||||
|
|
||||||
blueprints.push(b);
|
blueprints.push(b);
|
||||||
|
|
@ -101,6 +112,34 @@ pub fn generate_factory<L: Layouter, P: Pathfinder>(
|
||||||
blueprints.push(Blueprint::new());
|
blueprints.push(Blueprint::new());
|
||||||
used_connections.push((0, 0));
|
used_connections.push((0, 0));
|
||||||
}
|
}
|
||||||
|
Building::SideLoader => {
|
||||||
|
let mut blueprint = Blueprint::new();
|
||||||
|
blueprint.add_entity(Entity::new_belt(
|
||||||
|
Beltspeed::Fast,
|
||||||
|
Position::new(1, 1),
|
||||||
|
Direction::Up,
|
||||||
|
));
|
||||||
|
|
||||||
|
blocks.push(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,
|
||||||
|
}],
|
||||||
|
});
|
||||||
|
blueprints.push(blueprint);
|
||||||
|
used_connections.push((0, 0));
|
||||||
|
}
|
||||||
Building::BeltPool => todo!(),
|
Building::BeltPool => todo!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -112,7 +151,7 @@ pub fn generate_factory<L: Layouter, P: Pathfinder>(
|
||||||
endblock: c.to,
|
endblock: c.to,
|
||||||
endpoint: used_connections[c.to].1,
|
endpoint: used_connections[c.to].1,
|
||||||
lanes: 1,
|
lanes: 1,
|
||||||
beltspeed: Beltspeed::Normal,
|
beltspeed: Beltspeed::from_items_per_second(c.amount),
|
||||||
});
|
});
|
||||||
|
|
||||||
used_connections[c.from].0 += 1;
|
used_connections[c.from].0 += 1;
|
||||||
|
|
@ -122,16 +161,11 @@ pub fn generate_factory<L: Layouter, P: Pathfinder>(
|
||||||
// dbg!(&blocks);
|
// dbg!(&blocks);
|
||||||
// dbg!(&connections);
|
// dbg!(&connections);
|
||||||
|
|
||||||
let l = layouter
|
let layout_input = LayoutInput {
|
||||||
.layout(
|
blocks,
|
||||||
&LayoutInput {
|
connections,
|
||||||
blocks,
|
};
|
||||||
connections,
|
let l = layouter.layout(&layout_input, pathfinder, rng).unwrap();
|
||||||
},
|
|
||||||
pathfinder,
|
|
||||||
rng,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
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) {
|
||||||
|
|
@ -146,8 +180,8 @@ pub fn generate_factory<L: Layouter, P: Pathfinder>(
|
||||||
b.add_blueprint(assembly_blueprint);
|
b.add_blueprint(assembly_blueprint);
|
||||||
}
|
}
|
||||||
|
|
||||||
for path in &l.path_result {
|
for (path, connection) in l.path_result.iter().zip(layout_input.connections.iter()) {
|
||||||
b.add_path(&path[1..], Beltspeed::Fast);
|
b.add_path(&path[1..], connection.beltspeed);
|
||||||
}
|
}
|
||||||
|
|
||||||
b
|
b
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,20 @@ impl Beltspeed {
|
||||||
}
|
}
|
||||||
s
|
s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn from_items_per_second(x: f64) -> Self {
|
||||||
|
if x <= 15.0 {
|
||||||
|
Beltspeed::Normal
|
||||||
|
} else if x <= 30.0 {
|
||||||
|
Beltspeed::Fast
|
||||||
|
} else if x <= 45.0 {
|
||||||
|
Beltspeed::Express
|
||||||
|
} else if x <= 60.0 {
|
||||||
|
Beltspeed::Turbo
|
||||||
|
} else {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
|
||||||
|
|
|
||||||
|
|
@ -31,10 +31,11 @@ impl Layouter for GeneticAlgorithm {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
population.sort_by_key(|(_, s)| *s);
|
||||||
|
|
||||||
|
let mut best_result = population[0].clone();
|
||||||
|
|
||||||
for g in 0..self.generations {
|
for g in 0..self.generations {
|
||||||
population.sort_by_key(|(_, s)| *s);
|
|
||||||
|
|
||||||
for i in 0..(self.population_size - self.population_keep - self.population_new) {
|
for i in 0..(self.population_size - self.population_keep - self.population_new) {
|
||||||
loop {
|
loop {
|
||||||
let parent = &population[i % self.population_keep].0;
|
let parent = &population[i % self.population_keep].0;
|
||||||
|
|
@ -71,11 +72,13 @@ impl Layouter for GeneticAlgorithm {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
population.sort_by_key(|(_, s)| *s);
|
||||||
|
if population[0].1 < best_result.1 {
|
||||||
|
best_result = population[0].clone();
|
||||||
|
}
|
||||||
println!("completed generation {g}\nscore: {}", population[0].1);
|
println!("completed generation {g}\nscore: {}", population[0].1);
|
||||||
}
|
}
|
||||||
|
|
||||||
population.sort_by_key(|(_, s)| *s);
|
Some(best_result.0)
|
||||||
|
|
||||||
population.into_iter().next().map(|(l, _)| l)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ pub struct LayoutInput {
|
||||||
pub connections: Vec<Connection>,
|
pub connections: Vec<Connection>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct LayoutResult {
|
pub struct LayoutResult {
|
||||||
pub size: Position,
|
pub size: Position,
|
||||||
pub positions: Vec<Block>,
|
pub positions: Vec<Block>,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue