Add factory generator
This commit is contained in:
parent
295490858b
commit
6fbff67e61
14 changed files with 308 additions and 15 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
|
@ -566,7 +566,9 @@ dependencies = [
|
||||||
"clap 4.5.27",
|
"clap 4.5.27",
|
||||||
"factorio-blueprint",
|
"factorio-blueprint",
|
||||||
"factorio-core",
|
"factorio-core",
|
||||||
|
"factorio-layout",
|
||||||
"factorio-pathfinding",
|
"factorio-pathfinding",
|
||||||
|
"rand",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,9 @@ edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
factorio-pathfinding = { path = "../factorio-pathfinding" }
|
factorio-pathfinding = { path = "../factorio-pathfinding" }
|
||||||
|
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_json = "1.0.135"
|
serde_json = "1.0.135"
|
||||||
clap = { version = "4.5.26", features = ["derive"] }
|
clap = { version = "4.5.26", features = ["derive"] }
|
||||||
|
rand = { version = "0.8.5", features = ["small_rng"] }
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ pub fn assembly_line(assembly_machines: usize) -> Blueprint {
|
||||||
for i in 0..assembly_machines {
|
for i in 0..assembly_machines {
|
||||||
blueprint.add_entity(Entity::new_production(
|
blueprint.add_entity(Entity::new_production(
|
||||||
"assembling-machine-3",
|
"assembling-machine-3",
|
||||||
"iron-gears",
|
"iron-gear-wheel",
|
||||||
Position::new(3 + 6 * i as PositionType, 9),
|
Position::new(3 + 6 * i as PositionType, 9),
|
||||||
Direction::Up,
|
Direction::Up,
|
||||||
Position::new(6, 6),
|
Position::new(6, 6),
|
||||||
|
|
|
||||||
39
factorio-blueprint-generator/src/bin/generate_factory.rs
Normal file
39
factorio-blueprint-generator/src/bin/generate_factory.rs
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
use clap::Parser;
|
||||||
|
use factorio_blueprint::{BlueprintString, encode};
|
||||||
|
use factorio_blueprint_generator::factory::generate_factory;
|
||||||
|
use factorio_core::prelude::*;
|
||||||
|
use factorio_layout::valid_layout::ValidLayout;
|
||||||
|
use factorio_pathfinding::belt_finding::ConflictAvoidance;
|
||||||
|
use rand::{SeedableRng, rngs::SmallRng};
|
||||||
|
|
||||||
|
#[derive(Parser)]
|
||||||
|
struct Args {
|
||||||
|
#[arg(default_value_t = 0)]
|
||||||
|
seed: u64,
|
||||||
|
#[arg(short, long)]
|
||||||
|
json: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let args = Args::parse();
|
||||||
|
|
||||||
|
let l = ValidLayout {
|
||||||
|
max_tries: 10,
|
||||||
|
retries: 10,
|
||||||
|
start_size: Position::new(100, 100),
|
||||||
|
growth: Position::new(5, 5),
|
||||||
|
};
|
||||||
|
let p = ConflictAvoidance {
|
||||||
|
timeout: Some(std::time::Duration::from_millis(20)),
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut rng = SmallRng::seed_from_u64(args.seed);
|
||||||
|
|
||||||
|
let b = BlueprintString::Blueprint(generate_factory(&l, &p, &mut rng).to_blueprint());
|
||||||
|
|
||||||
|
if args.json {
|
||||||
|
println!("{}", serde_json::to_string_pretty(&b).unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("{}", encode(&serde_json::to_string(&b).unwrap()));
|
||||||
|
}
|
||||||
122
factorio-blueprint-generator/src/factory.rs
Normal file
122
factorio-blueprint-generator/src/factory.rs
Normal file
|
|
@ -0,0 +1,122 @@
|
||||||
|
use factorio_blueprint::abstraction::Blueprint;
|
||||||
|
use factorio_core::{beltoptions::Beltspeed, prelude::*};
|
||||||
|
use factorio_layout::{Connection, Interface, LayoutInput, Layouter, MacroBlock};
|
||||||
|
use factorio_pathfinding::Pathfinder;
|
||||||
|
use rand::Rng;
|
||||||
|
|
||||||
|
use crate::assembly::assembly_line;
|
||||||
|
|
||||||
|
pub fn generate_factory<L: Layouter, P: Pathfinder>(
|
||||||
|
layouter: &L,
|
||||||
|
pathfinder: &P,
|
||||||
|
rng: &mut impl Rng,
|
||||||
|
) -> Blueprint {
|
||||||
|
// 2 * gears
|
||||||
|
// 3 * copper wires
|
||||||
|
// 2 * green circuits
|
||||||
|
// 2 * inserter
|
||||||
|
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![
|
||||||
|
Connection {
|
||||||
|
startblock: 0,
|
||||||
|
startpoint: 0,
|
||||||
|
endblock: 3,
|
||||||
|
endpoint: 0,
|
||||||
|
lanes: 1,
|
||||||
|
beltspeed: Beltspeed::Fast,
|
||||||
|
},
|
||||||
|
Connection {
|
||||||
|
startblock: 1,
|
||||||
|
startpoint: 0,
|
||||||
|
endblock: 2,
|
||||||
|
endpoint: 0,
|
||||||
|
lanes: 1,
|
||||||
|
beltspeed: Beltspeed::Fast,
|
||||||
|
},
|
||||||
|
Connection {
|
||||||
|
startblock: 2,
|
||||||
|
startpoint: 0,
|
||||||
|
endblock: 3,
|
||||||
|
endpoint: 1,
|
||||||
|
lanes: 1,
|
||||||
|
beltspeed: Beltspeed::Fast,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
let l = layouter
|
||||||
|
.layout(
|
||||||
|
&LayoutInput {
|
||||||
|
blocks,
|
||||||
|
connections,
|
||||||
|
},
|
||||||
|
pathfinder,
|
||||||
|
rng,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let blueprints = vec![
|
||||||
|
assembly_line(2),
|
||||||
|
assembly_line(3),
|
||||||
|
assembly_line(2),
|
||||||
|
assembly_line(2),
|
||||||
|
];
|
||||||
|
|
||||||
|
let mut b = Blueprint::new();
|
||||||
|
for (block, mut assembly_blueprint) in l.positions.iter().zip(blueprints) {
|
||||||
|
let offset = match block.dir() {
|
||||||
|
Direction::Up => Position::new(0, 0),
|
||||||
|
Direction::Right => Position::new(2, 0),
|
||||||
|
Direction::Down => Position::new(2, 2),
|
||||||
|
Direction::Left => Position::new(0, 2),
|
||||||
|
};
|
||||||
|
assembly_blueprint.transform(Transformation::new(block.dir(), offset + 2 * block.pos()));
|
||||||
|
|
||||||
|
b.add_blueprint(assembly_blueprint);
|
||||||
|
}
|
||||||
|
|
||||||
|
for path in &l.path_result {
|
||||||
|
b.add_path(&path[1..], Beltspeed::Fast);
|
||||||
|
}
|
||||||
|
|
||||||
|
b
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
pub mod assembly;
|
pub mod assembly;
|
||||||
pub mod balancer;
|
pub mod balancer;
|
||||||
pub mod binary_merger;
|
pub mod binary_merger;
|
||||||
|
pub mod factory;
|
||||||
pub mod multistation;
|
pub mod multistation;
|
||||||
pub mod station;
|
pub mod station;
|
||||||
pub mod train;
|
pub mod train;
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ connections:
|
||||||
startpoint: 0
|
startpoint: 0
|
||||||
endblock: 0
|
endblock: 0
|
||||||
endpoint: 0
|
endpoint: 0
|
||||||
lanes: 1
|
lanes: 2
|
||||||
beltspeed: Normal
|
beltspeed: Normal
|
||||||
- startblock: 0
|
- startblock: 0
|
||||||
startpoint: 0
|
startpoint: 0
|
||||||
|
|
|
||||||
127
factorio-layout/new_layout3.yml
Normal file
127
factorio-layout/new_layout3.yml
Normal file
|
|
@ -0,0 +1,127 @@
|
||||||
|
size:
|
||||||
|
x: 50
|
||||||
|
y: 50
|
||||||
|
blocks:
|
||||||
|
- size:
|
||||||
|
x: 3
|
||||||
|
y: 2
|
||||||
|
input:
|
||||||
|
- offset:
|
||||||
|
x: 1
|
||||||
|
y: 1
|
||||||
|
dir: Up
|
||||||
|
output:
|
||||||
|
- offset:
|
||||||
|
x: 1
|
||||||
|
y: 0
|
||||||
|
dir: Up
|
||||||
|
- size:
|
||||||
|
x: 5
|
||||||
|
y: 2
|
||||||
|
input:
|
||||||
|
output:
|
||||||
|
- offset:
|
||||||
|
x: 1
|
||||||
|
y: 1
|
||||||
|
dir: Down
|
||||||
|
- size:
|
||||||
|
x: 5
|
||||||
|
y: 7
|
||||||
|
input:
|
||||||
|
- offset:
|
||||||
|
x: 0
|
||||||
|
y: 1
|
||||||
|
dir: Right
|
||||||
|
output:
|
||||||
|
- size:
|
||||||
|
x: 5
|
||||||
|
y: 5
|
||||||
|
input:
|
||||||
|
- offset:
|
||||||
|
x: 0
|
||||||
|
y: 1
|
||||||
|
dir: Right
|
||||||
|
output:
|
||||||
|
- offset:
|
||||||
|
x: 0
|
||||||
|
y: 3
|
||||||
|
dir: Left
|
||||||
|
- size:
|
||||||
|
x: 10
|
||||||
|
y: 10
|
||||||
|
input:
|
||||||
|
- offset:
|
||||||
|
x: 0
|
||||||
|
y: 1
|
||||||
|
dir: Right
|
||||||
|
- offset:
|
||||||
|
x: 0
|
||||||
|
y: 3
|
||||||
|
dir: Right
|
||||||
|
output:
|
||||||
|
- offset:
|
||||||
|
x: 9
|
||||||
|
y: 1
|
||||||
|
dir: Right
|
||||||
|
- offset:
|
||||||
|
x: 9
|
||||||
|
y: 3
|
||||||
|
dir: Right
|
||||||
|
- size:
|
||||||
|
x: 10
|
||||||
|
y: 5
|
||||||
|
input:
|
||||||
|
- offset:
|
||||||
|
x: 0
|
||||||
|
y: 1
|
||||||
|
dir: Right
|
||||||
|
- offset:
|
||||||
|
x: 0
|
||||||
|
y: 3
|
||||||
|
dir: Right
|
||||||
|
output:
|
||||||
|
- offset:
|
||||||
|
x: 9
|
||||||
|
y: 1
|
||||||
|
dir: Right
|
||||||
|
- offset:
|
||||||
|
x: 9
|
||||||
|
y: 3
|
||||||
|
dir: Right
|
||||||
|
connections:
|
||||||
|
- startblock: 1
|
||||||
|
startpoint: 0
|
||||||
|
endblock: 0
|
||||||
|
endpoint: 0
|
||||||
|
lanes: 2
|
||||||
|
beltspeed: Normal
|
||||||
|
- startblock: 0
|
||||||
|
startpoint: 0
|
||||||
|
endblock: 3
|
||||||
|
endpoint: 0
|
||||||
|
lanes: 1
|
||||||
|
beltspeed: Normal
|
||||||
|
- startblock: 3
|
||||||
|
startpoint: 0
|
||||||
|
endblock: 4
|
||||||
|
endpoint: 0
|
||||||
|
lanes: 1
|
||||||
|
beltspeed: Normal
|
||||||
|
- startblock: 4
|
||||||
|
startpoint: 0
|
||||||
|
endblock: 5
|
||||||
|
endpoint: 0
|
||||||
|
lanes: 1
|
||||||
|
beltspeed: Normal
|
||||||
|
- startblock: 4
|
||||||
|
startpoint: 1
|
||||||
|
endblock: 5
|
||||||
|
endpoint: 1
|
||||||
|
lanes: 1
|
||||||
|
beltspeed: Normal
|
||||||
|
- startblock: 5
|
||||||
|
startpoint: 0
|
||||||
|
endblock: 2
|
||||||
|
endpoint: 0
|
||||||
|
lanes: 1
|
||||||
|
beltspeed: Normal
|
||||||
|
|
@ -31,12 +31,12 @@ fn main() {
|
||||||
};
|
};
|
||||||
|
|
||||||
let p = ConflictAvoidance {
|
let p = ConflictAvoidance {
|
||||||
timeout: Some(std::time::Duration::from_millis(100)),
|
timeout: Some(std::time::Duration::from_millis(5)),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut rng = SmallRng::seed_from_u64(args.seed);
|
let mut rng = SmallRng::seed_from_u64(args.seed);
|
||||||
|
|
||||||
let r = l.layout(&problem, &p, &mut rng);
|
let r = l.layout(&problem, &p, &mut rng);
|
||||||
|
|
||||||
dbg!(r);
|
// dbg!(r);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -152,20 +152,20 @@ pub fn valid_path_layout<'a, R: Rng + ?Sized>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
pub(crate) struct MacroBlock {
|
pub(crate) struct MacroBlock {
|
||||||
pub(crate) size: Position,
|
pub(crate) size: Position,
|
||||||
pub(crate) input: Vec<Interface>,
|
pub(crate) input: Vec<Interface>,
|
||||||
pub(crate) output: Vec<Interface>,
|
pub(crate) output: Vec<Interface>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize, Clone, Copy)]
|
||||||
pub(crate) struct Interface {
|
pub(crate) struct Interface {
|
||||||
pub(crate) offset: Position,
|
pub(crate) offset: Position,
|
||||||
pub(crate) dir: Direction,
|
pub(crate) dir: Direction,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize, Clone, Copy)]
|
||||||
pub(crate) struct Connection {
|
pub(crate) struct Connection {
|
||||||
pub(crate) startblock: usize,
|
pub(crate) startblock: usize,
|
||||||
pub(crate) startpoint: usize,
|
pub(crate) startpoint: usize,
|
||||||
|
|
@ -173,7 +173,7 @@ pub(crate) struct Connection {
|
||||||
pub(crate) endpoint: usize,
|
pub(crate) endpoint: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
pub struct Problem {
|
pub struct Problem {
|
||||||
pub(crate) size: Position,
|
pub(crate) size: Position,
|
||||||
pub(crate) blocks: Vec<MacroBlock>,
|
pub(crate) blocks: Vec<MacroBlock>,
|
||||||
|
|
|
||||||
|
|
@ -3,21 +3,20 @@ use factorio_pathfinding::Pathfinder;
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
pub mod block;
|
|
||||||
pub mod genetic_algorithm_v1;
|
pub mod genetic_algorithm_v1;
|
||||||
pub mod genetic_algorithm_v2;
|
pub mod genetic_algorithm_v2;
|
||||||
pub mod layout;
|
pub mod layout;
|
||||||
pub mod misc;
|
pub mod misc;
|
||||||
pub mod valid_layout;
|
pub mod valid_layout;
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
pub struct MacroBlock {
|
pub struct MacroBlock {
|
||||||
pub size: Position,
|
pub size: Position,
|
||||||
pub input: Vec<Interface>,
|
pub input: Vec<Interface>,
|
||||||
pub output: Vec<Interface>,
|
pub output: Vec<Interface>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize, Clone, Copy)]
|
||||||
pub struct Interface {
|
pub struct Interface {
|
||||||
pub offset: Position,
|
pub offset: Position,
|
||||||
pub dir: Direction,
|
pub dir: Direction,
|
||||||
|
|
|
||||||
|
|
@ -267,7 +267,7 @@ impl ConflictAvoidance {
|
||||||
while b.next_finish_state(timeout) {
|
while b.next_finish_state(timeout) {
|
||||||
// println!("{}", b);
|
// println!("{}", b);
|
||||||
// b.print();
|
// b.print();
|
||||||
b.print_visualization();
|
// b.print_visualization();
|
||||||
let c = b.cost();
|
let c = b.cost();
|
||||||
if c < min_cost {
|
if c < min_cost {
|
||||||
min_cost = c;
|
min_cost = c;
|
||||||
|
|
|
||||||
|
|
@ -40,13 +40,14 @@ impl SinglePathfinder for ConflictAvoidance {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
p.print_visualization();
|
// p.print_visualization();
|
||||||
|
|
||||||
if p.find_path() {
|
if p.find_path() {
|
||||||
let mut c = conflict_avoidance::ConflictAvoidance::new(&p);
|
let mut c = conflict_avoidance::ConflictAvoidance::new(&p);
|
||||||
c.print_visualization();
|
// c.print_visualization();
|
||||||
|
|
||||||
if c.remove_all_conflicts(self.timeout) {
|
if c.remove_all_conflicts(self.timeout) {
|
||||||
|
c.print_visualization();
|
||||||
Some(c.get_paths().to_vec())
|
Some(c.get_paths().to_vec())
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ where
|
||||||
start_dir: c.start_dir,
|
start_dir: c.start_dir,
|
||||||
end_pos: c
|
end_pos: c
|
||||||
.end_pos
|
.end_pos
|
||||||
.in_direction(&c.start_dir.clockwise(), i as PositionType),
|
.in_direction(&c.end_dir.clockwise(), i as PositionType),
|
||||||
end_dir: c.end_dir,
|
end_dir: c.end_dir,
|
||||||
beltspeed: c.beltspeed,
|
beltspeed: c.beltspeed,
|
||||||
})
|
})
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue