Refactor layouting into separate crate
This commit is contained in:
parent
c3bb980fcf
commit
5c8010c23b
15 changed files with 124 additions and 55 deletions
16
Cargo.lock
generated
16
Cargo.lock
generated
|
|
@ -584,6 +584,21 @@ dependencies = [
|
|||
"termcolor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "factorio-layout"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"clap 4.5.26",
|
||||
"factorio-core",
|
||||
"factorio-pathfinding",
|
||||
"image",
|
||||
"miette",
|
||||
"rand",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_yaml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "factorio-pathfinding"
|
||||
version = "0.1.0"
|
||||
|
|
@ -599,7 +614,6 @@ dependencies = [
|
|||
"miette",
|
||||
"proptest",
|
||||
"proptest-derive",
|
||||
"rand",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_yaml",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
[workspace]
|
||||
members = [ "factorio-blueprint", "factorio-blueprint-generator", "factorio-core",
|
||||
members = [ "factorio-blueprint", "factorio-blueprint-generator", "factorio-core", "factorio-layout",
|
||||
"factorio-pathfinding"
|
||||
]
|
||||
resolver = "2"
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ fn main() {
|
|||
// ],
|
||||
8,
|
||||
)
|
||||
.0
|
||||
.to_blueprint(),
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,10 @@ fn calculate_station_height(
|
|||
station_height
|
||||
}
|
||||
|
||||
pub fn multistation(stations: &[StationSpec], stacker_size: usize) -> Blueprint {
|
||||
pub fn multistation(
|
||||
stations: &[StationSpec],
|
||||
stacker_size: usize,
|
||||
) -> (Blueprint, PositionType, Vec<PositionType>) {
|
||||
let longest_train = stations
|
||||
.iter()
|
||||
.map(|s| s.locomotives + s.wagons)
|
||||
|
|
@ -144,6 +147,7 @@ pub fn multistation(stations: &[StationSpec], stacker_size: usize) -> Blueprint
|
|||
|
||||
let inrail_x = 10 - 4 * stacker_length as PositionType;
|
||||
let outrail_x = inrail_x + 52 + 4 * (7 * longest_train).div_ceil(2) as PositionType;
|
||||
let mut output_heights = Vec::new();
|
||||
let mut previous_station_heights = 0;
|
||||
// station
|
||||
for (i, station) in stations.iter().enumerate() {
|
||||
|
|
@ -269,6 +273,8 @@ pub fn multistation(stations: &[StationSpec], stacker_size: usize) -> Blueprint
|
|||
let station_height =
|
||||
calculate_station_height(output_height, station.lanes, station.beltspeed);
|
||||
|
||||
output_heights.push(30 + total_stacker_height + previous_station_heights + output_height);
|
||||
|
||||
// rail crossing
|
||||
let (beltdirection, underground_left, underground_right) = match station.load {
|
||||
true => (
|
||||
|
|
@ -629,5 +635,5 @@ pub fn multistation(stations: &[StationSpec], stacker_size: usize) -> Blueprint
|
|||
|
||||
blueprint.transform(Transformation::new(Direction::Right, Position::new(0, 0)));
|
||||
|
||||
blueprint
|
||||
(blueprint, outrail_x + 5, output_heights)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,5 @@
|
|||
use factorio_core::{
|
||||
aabb::AABB,
|
||||
beltoptions::Beltspeed,
|
||||
direction,
|
||||
pathfield::PathField,
|
||||
prelude::{Direction, Position, PositionType, Transformable, Transformation},
|
||||
aabb::AABB, beltoptions::Beltspeed, pathfield::PathField, prelude::*,
|
||||
quaterdirection::QuaterDirection,
|
||||
};
|
||||
use std::{collections::HashMap, sync::atomic::AtomicUsize};
|
||||
|
|
|
|||
15
factorio-layout/Cargo.toml
Normal file
15
factorio-layout/Cargo.toml
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
[package]
|
||||
name = "factorio-layout"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
factorio-core = { path = "../factorio-core" }
|
||||
factorio-pathfinding = { path = "../factorio-pathfinding" }
|
||||
rand = { version = "0.8.5", features = ["small_rng"] }
|
||||
serde = { version = "1.0.192", features = ["derive"] }
|
||||
image = "0.25.2"
|
||||
serde_json = "1.0.108"
|
||||
clap = { version = "4.4.8", features = ["derive"] }
|
||||
miette = { version = "7.2.0", features = ["fancy"] }
|
||||
serde_yaml = "0.9.34"
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
use clap::{Parser, Subcommand};
|
||||
use factorio_core::visualize::Visualize;
|
||||
use factorio_pathfinding::layout::{genetic_algorithm2, GeneticAlgorithm, PathLayout};
|
||||
use factorio_layout::layout::{GeneticAlgorithm, PathLayout, genetic_algorithm2};
|
||||
use miette::{Context, IntoDiagnostic, Result};
|
||||
use rand::{rngs::SmallRng, SeedableRng};
|
||||
use rand::{SeedableRng, rngs::SmallRng};
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
use crate::belt_finding::conflict_avoidance::ConflictAvoidance;
|
||||
use factorio_core::{
|
||||
pathfield::PathField,
|
||||
prelude::*,
|
||||
visualize::{image_grid, Color, Symbol, Visualization, Visualize},
|
||||
visualize::{Color, Symbol, Visualization, Visualize, image_grid},
|
||||
};
|
||||
use rand::{seq::SliceRandom, Rng};
|
||||
use factorio_pathfinding::belt_finding::{self, conflict_avoidance::ConflictAvoidance};
|
||||
use rand::{Rng, seq::SliceRandom};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{sync::atomic::AtomicU32, time::Instant};
|
||||
|
||||
|
|
@ -195,9 +195,48 @@ pub struct PathLayout<'a> {
|
|||
score: usize,
|
||||
}
|
||||
|
||||
pub fn beltfinding_problem_from_layout(l: &Layout) -> belt_finding::Problem {
|
||||
let mut p = belt_finding::Problem::new(l.problem.size.x as usize, l.problem.size.y as usize);
|
||||
|
||||
for b in &l.blocks {
|
||||
let aabb = b.get_aabb();
|
||||
|
||||
p.set_blocked_range(
|
||||
aabb.min().x as usize,
|
||||
aabb.min().y as usize,
|
||||
aabb.max().x as usize,
|
||||
aabb.max().y as usize,
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
||||
for c in &l.problem.connections {
|
||||
let start_transform = l.blocks[c.startblock].block_to_world();
|
||||
let startpos = l.problem.blocks[c.startblock].output[c.startpoint]
|
||||
.offset
|
||||
.transform(start_transform);
|
||||
let startdir = l.problem.blocks[c.startblock].output[c.startpoint]
|
||||
.dir
|
||||
.transform(start_transform);
|
||||
let end_transform = l.blocks[c.endblock].block_to_world();
|
||||
let endpos = l.problem.blocks[c.endblock].input[c.endpoint]
|
||||
.offset
|
||||
.transform(end_transform);
|
||||
let enddir = l.problem.blocks[c.endblock].input[c.endpoint]
|
||||
.dir
|
||||
.transform(end_transform);
|
||||
p.add_connection(
|
||||
(startpos, startdir),
|
||||
(endpos.in_direction(&enddir, -1), enddir),
|
||||
);
|
||||
}
|
||||
|
||||
p
|
||||
}
|
||||
|
||||
impl<'a> PathLayout<'a> {
|
||||
pub fn new(layout: Layout<'a>) -> Option<PathLayout<'a>> {
|
||||
let mut p = crate::belt_finding::Problem::from_layout(&layout);
|
||||
let mut p = beltfinding_problem_from_layout(&layout);
|
||||
|
||||
if !p.find_path() {
|
||||
return None;
|
||||
|
|
@ -343,7 +382,7 @@ impl Layout<'_> {
|
|||
|
||||
let b = &problem.blocks[blocks.len()];
|
||||
for _ in 0..1000 {
|
||||
let dir = rng.gen::<Direction>();
|
||||
let dir = rng.r#gen::<Direction>();
|
||||
|
||||
let pos = match dir {
|
||||
Direction::Up => Position::new(
|
||||
|
|
@ -433,7 +472,7 @@ impl Layout<'_> {
|
|||
fn mutate_replace<R: Rng + ?Sized>(layout: &mut Layout, rng: &mut R) -> bool {
|
||||
let i = rng.gen_range(0..layout.blocks.len());
|
||||
|
||||
let dir = rng.gen::<Direction>();
|
||||
let dir = rng.r#gen::<Direction>();
|
||||
|
||||
let b = &layout.problem.blocks[i];
|
||||
|
||||
|
|
@ -492,7 +531,7 @@ impl Layout<'_> {
|
|||
|
||||
fn mutate_jiggle<R: Rng + ?Sized>(layout: &mut Layout, rng: &mut R) -> bool {
|
||||
let i = rng.gen_range(0..layout.blocks.len());
|
||||
let dir = rng.gen::<Direction>();
|
||||
let dir = rng.r#gen::<Direction>();
|
||||
let step = [(1, 10), (2, 5), (3, 5)]
|
||||
.choose_weighted(rng, |i| i.1)
|
||||
.unwrap()
|
||||
1
factorio-layout/src/lib.rs
Normal file
1
factorio-layout/src/lib.rs
Normal file
|
|
@ -0,0 +1 @@
|
|||
pub mod layout;
|
||||
|
|
@ -24,7 +24,6 @@ image = "0.25.2"
|
|||
miette = { version = "7.2.0", features = ["fancy"] }
|
||||
proptest = "1.5.0"
|
||||
proptest-derive = "0.5.0"
|
||||
rand = { version = "0.8.5", features = ["small_rng"] }
|
||||
serde = { version = "1.0.192", features = ["derive"] }
|
||||
serde_json = "1.0.108"
|
||||
serde_yaml = "0.9.34"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
use crate::graph::wheighted_graph::shortest_path::dijkstra;
|
||||
use crate::graph::wheighted_graph::WheightedGraph;
|
||||
use crate::layout::Layout;
|
||||
use crate::misc::Map;
|
||||
use crate::priority_queue::BinaryHeap;
|
||||
use factorio_core::{prelude::*, visualize::Visualize};
|
||||
|
|
@ -34,44 +33,44 @@ impl Problem {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn from_layout(l: &Layout) -> Self {
|
||||
let mut p = Self::new(l.problem.size.x as usize, l.problem.size.y as usize);
|
||||
// pub fn from_layout(l: &Layout) -> Self {
|
||||
// let mut p = Self::new(l.problem.size.x as usize, l.problem.size.y as usize);
|
||||
|
||||
for b in &l.blocks {
|
||||
let aabb = b.get_aabb();
|
||||
// for b in &l.blocks {
|
||||
// let aabb = b.get_aabb();
|
||||
|
||||
p.set_blocked_range(
|
||||
aabb.min().x as usize,
|
||||
aabb.min().y as usize,
|
||||
aabb.max().x as usize,
|
||||
aabb.max().y as usize,
|
||||
true,
|
||||
);
|
||||
}
|
||||
// p.set_blocked_range(
|
||||
// aabb.min().x as usize,
|
||||
// aabb.min().y as usize,
|
||||
// aabb.max().x as usize,
|
||||
// aabb.max().y as usize,
|
||||
// true,
|
||||
// );
|
||||
// }
|
||||
|
||||
for c in &l.problem.connections {
|
||||
let start_transform = l.blocks[c.startblock].block_to_world();
|
||||
let startpos = l.problem.blocks[c.startblock].output[c.startpoint]
|
||||
.offset
|
||||
.transform(start_transform);
|
||||
let startdir = l.problem.blocks[c.startblock].output[c.startpoint]
|
||||
.dir
|
||||
.transform(start_transform);
|
||||
let end_transform = l.blocks[c.endblock].block_to_world();
|
||||
let endpos = l.problem.blocks[c.endblock].input[c.endpoint]
|
||||
.offset
|
||||
.transform(end_transform);
|
||||
let enddir = l.problem.blocks[c.endblock].input[c.endpoint]
|
||||
.dir
|
||||
.transform(end_transform);
|
||||
p.add_connection(
|
||||
(startpos, startdir),
|
||||
(endpos.in_direction(&enddir, -1), enddir),
|
||||
);
|
||||
}
|
||||
// for c in &l.problem.connections {
|
||||
// let start_transform = l.blocks[c.startblock].block_to_world();
|
||||
// let startpos = l.problem.blocks[c.startblock].output[c.startpoint]
|
||||
// .offset
|
||||
// .transform(start_transform);
|
||||
// let startdir = l.problem.blocks[c.startblock].output[c.startpoint]
|
||||
// .dir
|
||||
// .transform(start_transform);
|
||||
// let end_transform = l.blocks[c.endblock].block_to_world();
|
||||
// let endpos = l.problem.blocks[c.endblock].input[c.endpoint]
|
||||
// .offset
|
||||
// .transform(end_transform);
|
||||
// let enddir = l.problem.blocks[c.endblock].input[c.endpoint]
|
||||
// .dir
|
||||
// .transform(end_transform);
|
||||
// p.add_connection(
|
||||
// (startpos, startdir),
|
||||
// (endpos.in_direction(&enddir, -1), enddir),
|
||||
// );
|
||||
// }
|
||||
|
||||
p
|
||||
}
|
||||
// p
|
||||
// }
|
||||
|
||||
pub fn add_connection(&mut self, start: (Position, Direction), end: (Position, Direction)) {
|
||||
self.start.push(start);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
pub mod belt_finding;
|
||||
pub mod graph;
|
||||
pub mod layout;
|
||||
pub mod misc;
|
||||
pub mod priority_queue;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue