Add Layout trait
This commit is contained in:
parent
00eda50872
commit
295490858b
12 changed files with 407 additions and 41 deletions
94
Cargo.lock
generated
94
Cargo.lock
generated
|
|
@ -259,9 +259,9 @@ checksum = "c360505aed52b7ec96a3636c3f039d99103c37d1d9b4f7a8c743d3ea9ffcd03b"
|
|||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.16.0"
|
||||
version = "3.17.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
|
||||
checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf"
|
||||
|
||||
[[package]]
|
||||
name = "bytemuck"
|
||||
|
|
@ -327,9 +327,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.5.26"
|
||||
version = "4.5.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8eb5e908ef3a6efbe1ed62520fb7287959888c88485abe072543190ecc66783"
|
||||
checksum = "769b0145982b4b48713e01ec42d61614425f27b7058bda7180a3a41f30104796"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
"clap_derive",
|
||||
|
|
@ -337,9 +337,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.5.26"
|
||||
version = "4.5.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96b01801b5fc6a0a232407abc821660c9c6d25a1cafc0d4f85f29fb8d9afc121"
|
||||
checksum = "1b26884eb4b57140e4d2d93652abfa49498b938b3c9179f9fc487b0acc3edad7"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
|
|
@ -449,9 +449,9 @@ checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
|
|||
|
||||
[[package]]
|
||||
name = "crunchy"
|
||||
version = "0.2.2"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
|
||||
checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929"
|
||||
|
||||
[[package]]
|
||||
name = "csv"
|
||||
|
|
@ -552,7 +552,7 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"bon",
|
||||
"clap 4.5.26",
|
||||
"clap 4.5.27",
|
||||
"factorio-core",
|
||||
"flate2",
|
||||
"serde",
|
||||
|
|
@ -563,7 +563,7 @@ dependencies = [
|
|||
name = "factorio-blueprint-generator"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"clap 4.5.26",
|
||||
"clap 4.5.27",
|
||||
"factorio-blueprint",
|
||||
"factorio-core",
|
||||
"factorio-pathfinding",
|
||||
|
|
@ -574,7 +574,7 @@ dependencies = [
|
|||
name = "factorio-core"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"clap 4.5.26",
|
||||
"clap 4.5.27",
|
||||
"criterion",
|
||||
"image",
|
||||
"proptest",
|
||||
|
|
@ -588,7 +588,7 @@ dependencies = [
|
|||
name = "factorio-layout"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"clap 4.5.26",
|
||||
"clap 4.5.27",
|
||||
"factorio-core",
|
||||
"factorio-pathfinding",
|
||||
"image",
|
||||
|
|
@ -605,7 +605,7 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"base64 0.21.7",
|
||||
"bon",
|
||||
"clap 4.5.26",
|
||||
"clap 4.5.27",
|
||||
"criterion",
|
||||
"factorio-blueprint",
|
||||
"factorio-core",
|
||||
|
|
@ -659,7 +659,19 @@ checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
|
|||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi 0.13.3+wasi-0.2.2",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -762,9 +774,9 @@ checksum = "d0263a3d970d5c054ed9312c0057b4f3bde9c0b33836d3637361d4a9e6e7a408"
|
|||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.7.0"
|
||||
version = "2.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f"
|
||||
checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown",
|
||||
|
|
@ -862,9 +874,9 @@ checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
|
|||
|
||||
[[package]]
|
||||
name = "libfuzzer-sys"
|
||||
version = "0.4.8"
|
||||
version = "0.4.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b9569d2f74e257076d8c6bfa73fb505b46b851e51ddaecc825944aa3bed17fa"
|
||||
checksum = "cf78f52d400cf2d84a3a973a78a592b4adc535739e0a5597a0da6f0c357adc75"
|
||||
dependencies = [
|
||||
"arbitrary",
|
||||
"cc",
|
||||
|
|
@ -1241,7 +1253,7 @@ version = "0.6.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"getrandom 0.2.15",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1366,9 +1378,9 @@ checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
|
|||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.43"
|
||||
version = "0.38.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a78891ee6bf2340288408954ac787aa063d8e8817e9f53abb37c695c6d834ef6"
|
||||
checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154"
|
||||
dependencies = [
|
||||
"bitflags 2.8.0",
|
||||
"errno",
|
||||
|
|
@ -1397,9 +1409,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.18"
|
||||
version = "1.0.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
|
||||
checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd"
|
||||
|
||||
[[package]]
|
||||
name = "same-file"
|
||||
|
|
@ -1442,9 +1454,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.135"
|
||||
version = "1.0.138"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b0d7ba2887406110130a978386c4e1befb98c674b4fba677954e4db976630d9"
|
||||
checksum = "d434192e7da787e94a6ea7e9670b26a036d0ca41e0b7efb2676dd32bae872949"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"memchr",
|
||||
|
|
@ -1560,13 +1572,13 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
|
|||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.15.0"
|
||||
version = "3.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a8a559c81686f576e8cd0290cd2a24a2a9ad80c98b3478856500fcbd7acd704"
|
||||
checksum = "38c246215d7d24f48ae091a2902398798e05d978b24315d6efbc00ede9a8bb91"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"fastrand",
|
||||
"getrandom",
|
||||
"getrandom 0.3.1",
|
||||
"once_cell",
|
||||
"rustix",
|
||||
"windows-sys",
|
||||
|
|
@ -1693,9 +1705,9 @@ checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94"
|
|||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.14"
|
||||
version = "1.0.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
|
||||
checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-linebreak"
|
||||
|
|
@ -1763,6 +1775,15 @@ version = "0.11.0+wasi-snapshot-preview1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.13.3+wasi-0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2"
|
||||
dependencies = [
|
||||
"wit-bindgen-rt",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.100"
|
||||
|
|
@ -1943,13 +1964,22 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
|||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.6.24"
|
||||
version = "0.6.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c8d71a593cc5c42ad7876e2c1fda56f314f3754c084128833e64f1345ff8a03a"
|
||||
checksum = "ad699df48212c6cc6eb4435f35500ac6fd3b9913324f938aea302022ce19d310"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen-rt"
|
||||
version = "0.33.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c"
|
||||
dependencies = [
|
||||
"bitflags 2.8.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.7.35"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use clap::ValueEnum;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum, Serialize, Deserialize)]
|
||||
pub enum Beltspeed {
|
||||
Normal,
|
||||
Fast,
|
||||
|
|
|
|||
49
factorio-layout/new_layout.yaml
Normal file
49
factorio-layout/new_layout.yaml
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
|
||||
size:
|
||||
x: 15
|
||||
y: 15
|
||||
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:
|
||||
connections:
|
||||
- startblock: 1
|
||||
startpoint: 0
|
||||
endblock: 0
|
||||
endpoint: 0
|
||||
lanes: 1
|
||||
beltspeed: Normal
|
||||
- startblock: 0
|
||||
startpoint: 0
|
||||
endblock: 2
|
||||
endpoint: 0
|
||||
lanes: 1
|
||||
beltspeed: Normal
|
||||
42
factorio-layout/src/bin/new_layout.rs
Normal file
42
factorio-layout/src/bin/new_layout.rs
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
use std::path::PathBuf;
|
||||
|
||||
use clap::Parser;
|
||||
use factorio_core::prelude::Position;
|
||||
use factorio_layout::{Layouter, valid_layout::ValidLayout};
|
||||
use factorio_pathfinding::belt_finding::ConflictAvoidance;
|
||||
use rand::{SeedableRng, rngs::SmallRng};
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
struct Args {
|
||||
#[clap(short, long, default_value_t = 0)]
|
||||
seed: u64,
|
||||
|
||||
path: PathBuf,
|
||||
// #[command(subcommand)]
|
||||
// subcommand: Commands,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let args = Args::parse();
|
||||
|
||||
let file = std::fs::File::open(args.path).unwrap();
|
||||
|
||||
let problem = serde_yaml::from_reader(file).unwrap();
|
||||
|
||||
let l = ValidLayout {
|
||||
max_tries: 100,
|
||||
retries: 10,
|
||||
start_size: Position::new(10, 10),
|
||||
growth: Position::new(2, 2),
|
||||
};
|
||||
|
||||
let p = ConflictAvoidance {
|
||||
timeout: Some(std::time::Duration::from_millis(100)),
|
||||
};
|
||||
|
||||
let mut rng = SmallRng::seed_from_u64(args.seed);
|
||||
|
||||
let r = l.layout(&problem, &p, &mut rng);
|
||||
|
||||
dbg!(r);
|
||||
}
|
||||
0
factorio-layout/src/genetic_algorithm_v1.rs
Normal file
0
factorio-layout/src/genetic_algorithm_v1.rs
Normal file
21
factorio-layout/src/genetic_algorithm_v2.rs
Normal file
21
factorio-layout/src/genetic_algorithm_v2.rs
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
use factorio_pathfinding::Pathfinder;
|
||||
use rand::Rng;
|
||||
|
||||
use crate::Layouter;
|
||||
|
||||
pub struct GeneticAlgorithmV2 {
|
||||
pub new_layouts: usize,
|
||||
pub mutation_timeout: usize,
|
||||
pub max_mutations: usize,
|
||||
}
|
||||
|
||||
impl Layouter for GeneticAlgorithmV2 {
|
||||
fn layout<R: Rng, P: Pathfinder>(
|
||||
&self,
|
||||
input: &crate::LayoutInput,
|
||||
pathfinder: &P,
|
||||
rng: &mut R,
|
||||
) -> Option<crate::LayoutResult> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +1,55 @@
|
|||
use factorio_core::{beltoptions::Beltspeed, pathfield::PathField, prelude::*};
|
||||
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)]
|
||||
pub struct MacroBlock {
|
||||
pub size: Position,
|
||||
pub input: Vec<Interface>,
|
||||
pub output: Vec<Interface>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct Interface {
|
||||
pub offset: Position,
|
||||
pub dir: Direction,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct Connection {
|
||||
pub startblock: usize,
|
||||
pub startpoint: usize,
|
||||
pub endblock: usize,
|
||||
pub endpoint: usize,
|
||||
pub lanes: usize,
|
||||
pub beltspeed: Beltspeed,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct LayoutInput {
|
||||
pub blocks: Vec<MacroBlock>,
|
||||
pub connections: Vec<Connection>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct LayoutResult {
|
||||
pub positions: Vec<Block>,
|
||||
pub path_result: Vec<Vec<PathField>>,
|
||||
}
|
||||
|
||||
pub trait Layouter {
|
||||
fn layout<R: Rng, P: Pathfinder>(
|
||||
&self,
|
||||
input: &LayoutInput,
|
||||
pathfinder: &P,
|
||||
rng: &mut R,
|
||||
) -> Option<LayoutResult>;
|
||||
}
|
||||
|
|
|
|||
119
factorio-layout/src/misc.rs
Normal file
119
factorio-layout/src/misc.rs
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
use crate::LayoutInput;
|
||||
use factorio_core::prelude::*;
|
||||
use factorio_pathfinding::{Connection, PathInput, examples::HashMapMap};
|
||||
use rand::Rng;
|
||||
|
||||
pub fn initally_set_blocks(
|
||||
input: &LayoutInput,
|
||||
size: Position,
|
||||
retries: usize,
|
||||
rng: &mut impl Rng,
|
||||
) -> Option<Vec<Block>> {
|
||||
let mut blocks = Vec::new();
|
||||
|
||||
let mut aabbs = Vec::new();
|
||||
|
||||
if place_block(input, size, retries, &mut blocks, &mut aabbs, rng) {
|
||||
Some(blocks)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn place_block(
|
||||
input: &LayoutInput,
|
||||
size: Position,
|
||||
retries: usize,
|
||||
blocks: &mut Vec<Block>,
|
||||
aabbs: &mut Vec<AABB>,
|
||||
rng: &mut impl Rng,
|
||||
) -> bool {
|
||||
if input.blocks.len() == blocks.len() {
|
||||
return true;
|
||||
}
|
||||
|
||||
let b = &input.blocks[blocks.len()];
|
||||
for _ in 0..retries {
|
||||
let dir = rng.r#gen::<Direction>();
|
||||
|
||||
let pos = match dir {
|
||||
Direction::Up => Position::new(
|
||||
rng.gen_range(0..=(size.x - b.size.x)),
|
||||
rng.gen_range(0..=(size.y - b.size.y)),
|
||||
),
|
||||
Direction::Right => Position::new(
|
||||
rng.gen_range((b.size.y - 1)..size.x),
|
||||
rng.gen_range(0..=(size.y - b.size.x)),
|
||||
),
|
||||
Direction::Down => Position::new(
|
||||
rng.gen_range((b.size.x - 1)..size.x),
|
||||
rng.gen_range((b.size.y - 1)..size.y),
|
||||
),
|
||||
Direction::Left => Position::new(
|
||||
rng.gen_range(0..=(size.x - b.size.y)),
|
||||
rng.gen_range((b.size.x - 1)..size.y),
|
||||
),
|
||||
};
|
||||
|
||||
let current = Block::new(pos, dir, b.size);
|
||||
let current_aabb = current.get_aabb();
|
||||
|
||||
if aabbs.iter().all(|&b| !AABB::collision(b, current_aabb)) {
|
||||
blocks.push(current);
|
||||
aabbs.push(current_aabb);
|
||||
|
||||
if place_block(input, size, retries, blocks, aabbs, rng) {
|
||||
return true;
|
||||
}
|
||||
|
||||
blocks.pop();
|
||||
aabbs.pop();
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
pub fn path_input_from_blocks_positions(
|
||||
input: &LayoutInput,
|
||||
size: Position,
|
||||
block_positions: &[Block],
|
||||
) -> (Vec<Connection>, HashMapMap) {
|
||||
let mut map = HashMapMap::new(size);
|
||||
|
||||
let mut connections = Vec::new();
|
||||
|
||||
for b in block_positions {
|
||||
let aabb = b.get_aabb();
|
||||
|
||||
map.set_blocked_range(aabb.min(), aabb.max(), true);
|
||||
}
|
||||
|
||||
for c in &input.connections {
|
||||
let start_transform = block_positions[c.startblock].block_to_world();
|
||||
let start_pos = input.blocks[c.startblock].output[c.startpoint]
|
||||
.offset
|
||||
.transform(start_transform);
|
||||
let start_dir = input.blocks[c.startblock].output[c.startpoint]
|
||||
.dir
|
||||
.transform(start_transform);
|
||||
let end_transform = block_positions[c.endblock].block_to_world();
|
||||
let end_pos = input.blocks[c.endblock].input[c.endpoint]
|
||||
.offset
|
||||
.transform(end_transform);
|
||||
let end_dir = input.blocks[c.endblock].input[c.endpoint]
|
||||
.dir
|
||||
.transform(end_transform);
|
||||
|
||||
connections.push(Connection {
|
||||
start_pos,
|
||||
start_dir,
|
||||
end_pos,
|
||||
end_dir,
|
||||
beltspeed: c.beltspeed,
|
||||
lanes: c.lanes,
|
||||
});
|
||||
}
|
||||
|
||||
(connections, map)
|
||||
}
|
||||
44
factorio-layout/src/valid_layout.rs
Normal file
44
factorio-layout/src/valid_layout.rs
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
use factorio_core::prelude::{Position, PositionType};
|
||||
use factorio_pathfinding::Pathfinder;
|
||||
use rand::Rng;
|
||||
|
||||
use crate::{
|
||||
LayoutResult, Layouter,
|
||||
misc::{initally_set_blocks, path_input_from_blocks_positions},
|
||||
};
|
||||
|
||||
pub struct ValidLayout {
|
||||
pub max_tries: usize,
|
||||
pub retries: usize,
|
||||
pub start_size: Position,
|
||||
pub growth: Position,
|
||||
}
|
||||
|
||||
impl Layouter for ValidLayout {
|
||||
fn layout<R: Rng, P: Pathfinder>(
|
||||
&self,
|
||||
input: &crate::LayoutInput,
|
||||
pathfinder: &P,
|
||||
rng: &mut R,
|
||||
) -> Option<LayoutResult> {
|
||||
for i in 0..self.max_tries {
|
||||
let size = self.start_size + i as PositionType * self.growth;
|
||||
|
||||
if let Some(blocks) = initally_set_blocks(input, size, self.retries, rng) {
|
||||
let (connections, map) = path_input_from_blocks_positions(input, size, &blocks);
|
||||
|
||||
if let Some(paths) = pathfinder.find_paths(factorio_pathfinding::PathInput {
|
||||
connections: &connections,
|
||||
map,
|
||||
}) {
|
||||
return Some(LayoutResult {
|
||||
positions: blocks,
|
||||
path_result: paths,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
}
|
||||
|
|
@ -14,13 +14,13 @@ pub mod brute_force;
|
|||
pub mod conflict_avoidance;
|
||||
|
||||
pub struct ConflictAvoidance {
|
||||
timeout: Option<std::time::Duration>,
|
||||
pub timeout: Option<std::time::Duration>,
|
||||
}
|
||||
|
||||
impl SinglePathfinder for ConflictAvoidance {
|
||||
fn find_paths<M: crate::Map>(
|
||||
&self,
|
||||
input: SinglePathInput<'_, M>,
|
||||
input: SinglePathInput<M>,
|
||||
) -> Option<Vec<Vec<factorio_core::pathfield::PathField>>> {
|
||||
let (pos, size) = input.map.area();
|
||||
let mut p = Problem::new(size.x as usize, size.y as usize);
|
||||
|
|
@ -34,11 +34,17 @@ impl SinglePathfinder for ConflictAvoidance {
|
|||
}
|
||||
|
||||
for i in input.connections {
|
||||
p.add_connection((i.start_pos, i.start_dir), (i.end_pos, i.end_dir));
|
||||
p.add_connection(
|
||||
(i.start_pos, i.start_dir),
|
||||
(i.end_pos.in_direction(&i.end_dir, -1), i.end_dir),
|
||||
);
|
||||
}
|
||||
|
||||
p.print_visualization();
|
||||
|
||||
if p.find_path() {
|
||||
let mut c = conflict_avoidance::ConflictAvoidance::new(&p);
|
||||
c.print_visualization();
|
||||
|
||||
if c.remove_all_conflicts(self.timeout) {
|
||||
Some(c.get_paths().to_vec())
|
||||
|
|
|
|||
|
|
@ -12,14 +12,14 @@ pub struct HashMapMap {
|
|||
}
|
||||
|
||||
impl HashMapMap {
|
||||
fn new(size: impl Into<Position>) -> Self {
|
||||
pub fn new(size: impl Into<Position>) -> Self {
|
||||
Self {
|
||||
map: HashSet::new(),
|
||||
size: size.into(),
|
||||
}
|
||||
}
|
||||
|
||||
fn set_blocked_range(
|
||||
pub fn set_blocked_range(
|
||||
&mut self,
|
||||
min_pos: impl Into<Position>,
|
||||
max_pos: impl Into<Position>,
|
||||
|
|
@ -35,7 +35,7 @@ impl HashMapMap {
|
|||
}
|
||||
}
|
||||
|
||||
fn set_blocked(&mut self, pos: impl Into<Position>, block: bool) {
|
||||
pub fn set_blocked(&mut self, pos: impl Into<Position>, block: bool) {
|
||||
let pos = pos.into();
|
||||
if block {
|
||||
self.map.insert(pos);
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ pub mod misc;
|
|||
pub mod priority_queue;
|
||||
|
||||
pub struct PathInput<'c, M> {
|
||||
connections: &'c [Connection],
|
||||
map: M,
|
||||
pub connections: &'c [Connection],
|
||||
pub map: M,
|
||||
}
|
||||
|
||||
pub struct Connection {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue