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",
|
||||
"factorio-blueprint",
|
||||
"factorio-core",
|
||||
"factorio-layout",
|
||||
"factorio-pathfinding",
|
||||
"rand",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,9 @@ edition = "2024"
|
|||
|
||||
[dependencies]
|
||||
factorio-pathfinding = { path = "../factorio-pathfinding" }
|
||||
factorio-layout = { path = "../factorio-layout" }
|
||||
factorio-core = { path = "../factorio-core" }
|
||||
factorio-blueprint = { path = "../factorio-blueprint" }
|
||||
serde_json = "1.0.135"
|
||||
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 {
|
||||
blueprint.add_entity(Entity::new_production(
|
||||
"assembling-machine-3",
|
||||
"iron-gears",
|
||||
"iron-gear-wheel",
|
||||
Position::new(3 + 6 * i as PositionType, 9),
|
||||
Direction::Up,
|
||||
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 balancer;
|
||||
pub mod binary_merger;
|
||||
pub mod factory;
|
||||
pub mod multistation;
|
||||
pub mod station;
|
||||
pub mod train;
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ connections:
|
|||
startpoint: 0
|
||||
endblock: 0
|
||||
endpoint: 0
|
||||
lanes: 1
|
||||
lanes: 2
|
||||
beltspeed: Normal
|
||||
- startblock: 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 {
|
||||
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 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) size: Position,
|
||||
pub(crate) input: Vec<Interface>,
|
||||
pub(crate) output: Vec<Interface>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, Copy)]
|
||||
pub(crate) struct Interface {
|
||||
pub(crate) offset: Position,
|
||||
pub(crate) dir: Direction,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, Copy)]
|
||||
pub(crate) struct Connection {
|
||||
pub(crate) startblock: usize,
|
||||
pub(crate) startpoint: usize,
|
||||
|
|
@ -173,7 +173,7 @@ pub(crate) struct Connection {
|
|||
pub(crate) endpoint: usize,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct Problem {
|
||||
pub(crate) size: Position,
|
||||
pub(crate) blocks: Vec<MacroBlock>,
|
||||
|
|
|
|||
|
|
@ -3,21 +3,20 @@ use factorio_pathfinding::Pathfinder;
|
|||
use rand::Rng;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
pub mod block;
|
||||
pub mod genetic_algorithm_v1;
|
||||
pub mod genetic_algorithm_v2;
|
||||
pub mod layout;
|
||||
pub mod misc;
|
||||
pub mod valid_layout;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct MacroBlock {
|
||||
pub size: Position,
|
||||
pub input: Vec<Interface>,
|
||||
pub output: Vec<Interface>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, Copy)]
|
||||
pub struct Interface {
|
||||
pub offset: Position,
|
||||
pub dir: Direction,
|
||||
|
|
|
|||
|
|
@ -267,7 +267,7 @@ impl ConflictAvoidance {
|
|||
while b.next_finish_state(timeout) {
|
||||
// println!("{}", b);
|
||||
// b.print();
|
||||
b.print_visualization();
|
||||
// b.print_visualization();
|
||||
let c = b.cost();
|
||||
if c < min_cost {
|
||||
min_cost = c;
|
||||
|
|
|
|||
|
|
@ -40,13 +40,14 @@ impl SinglePathfinder for ConflictAvoidance {
|
|||
);
|
||||
}
|
||||
|
||||
p.print_visualization();
|
||||
// p.print_visualization();
|
||||
|
||||
if p.find_path() {
|
||||
let mut c = conflict_avoidance::ConflictAvoidance::new(&p);
|
||||
c.print_visualization();
|
||||
// c.print_visualization();
|
||||
|
||||
if c.remove_all_conflicts(self.timeout) {
|
||||
c.print_visualization();
|
||||
Some(c.get_paths().to_vec())
|
||||
} else {
|
||||
None
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ where
|
|||
start_dir: c.start_dir,
|
||||
end_pos: c
|
||||
.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,
|
||||
beltspeed: c.beltspeed,
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue