Add belt finding to layouting

This commit is contained in:
hal8174 2024-08-25 00:08:02 +02:00
parent c572fcb0e2
commit 5a6be3194e
4 changed files with 114 additions and 31 deletions

View file

@ -1,4 +1,8 @@
use factorio_blueprint::{common::visualize::Visualize, layout::Layout}; use factorio_blueprint::{
belt_finding::{conflict_avoidance::ConflictAvoidance, Problem},
common::visualize::Visualize,
layout::Layout,
};
use rand::SeedableRng; use rand::SeedableRng;
fn main() { fn main() {
@ -15,13 +19,29 @@ fn main() {
let p = serde_yaml::from_reader(file).unwrap(); let p = serde_yaml::from_reader(file).unwrap();
for i in 0..100 { for i in 0..1 {
let mut rng = rand::rngs::SmallRng::seed_from_u64(i); let mut rng = rand::rngs::SmallRng::seed_from_u64(5);
let l = Layout::new(&p, &mut rng); let l = Layout::new(&p, &mut rng);
println!("Seed: {i}, Score {}", l.score()); // let s = l.score();
l.print_visualization(); l.print_visualization();
let mut p = Problem::from_layout(&l);
p.print();
p.find_path();
p.print();
let mut c = ConflictAvoidance::new(p);
c.remove_all_conflicts();
c.print();
// println!("Seed: {i}, Score {}", s);
// l.print_visualization();
// if s < min {
// min = s;
// min_l = Some(l);
// }
} }
} }

View file

@ -1,6 +1,6 @@
size: size:
x: 10 x: 15
y: 10 y: 15
blocks: blocks:
- size: - size:
x: 3 x: 3
@ -9,7 +9,7 @@ blocks:
- offset: - offset:
x: 1 x: 1
y: 1 y: 1
dir: Down dir: Up
output: output:
- offset: - offset:
x: 1 x: 1
@ -31,10 +31,14 @@ blocks:
- offset: - offset:
x: 0 x: 0
y: 1 y: 1
dir: Left dir: Right
output: output:
connections: connections:
- startblock: 1 - startblock: 1
startpoint: 0 startpoint: 0
endblock: 0 endblock: 0
endpoint: 0 endpoint: 0
- startblock: 0
startpoint: 0
endblock: 2
endpoint: 0

View file

@ -1,5 +1,6 @@
use crate::common::color::COLORS; use crate::common::color::COLORS;
use crate::graph::wheighted_graph::WheightedGraph; use crate::graph::wheighted_graph::WheightedGraph;
use crate::layout::Layout;
use crate::misc::Map; use crate::misc::Map;
use crate::{ use crate::{
graph::wheighted_graph::shortest_path::dijkstra, priority_queue::fibonacci_heap::FibonacciHeap, graph::wheighted_graph::shortest_path::dijkstra, priority_queue::fibonacci_heap::FibonacciHeap,
@ -36,6 +37,49 @@ 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);
for ((pos, dir), b) in l.blocks.iter().zip(l.problem.blocks.iter()) {
let (npos, nsize) = Layout::normalize_pos((b, *pos, *dir));
let nend = npos + nsize - Position::new(1, 1);
p.set_blocked_range(
npos.x as usize,
npos.y as usize,
nend.x as usize,
nend.y as usize,
true,
);
}
for c in &l.problem.connections {
let startpos = Layout::transform(
l.blocks[c.startblock].0,
l.blocks[c.startblock].1,
l.problem.blocks[c.startblock].output[c.startpoint].offset,
);
let startdir = Layout::rotate(
l.problem.blocks[c.startblock].output[c.startpoint].dir,
l.blocks[c.startblock].1,
);
let enddir = Layout::rotate(
l.problem.blocks[c.endblock].input[c.endpoint].dir,
l.blocks[c.endblock].1,
);
let endpos = Layout::transform(
l.blocks[c.endblock].0,
l.blocks[c.endblock].1,
l.problem.blocks[c.endblock].input[c.endpoint].offset,
)
.in_direction(&enddir, -1);
p.add_connection((startpos, startdir), (endpos, enddir));
}
p
}
pub fn add_connection(&mut self, start: (Position, Direction), end: (Position, Direction)) { pub fn add_connection(&mut self, start: (Position, Direction), end: (Position, Direction)) {
self.start.push(start); self.start.push(start);
self.end.push(end); self.end.push(end);

View file

@ -1,37 +1,34 @@
use crate::common::visualize::{Color, Symbol, Visualization, Visualize}; use crate::common::visualize::{Color, Symbol, Visualization, Visualize};
use crate::prelude::*; use crate::prelude::*;
use crate::{belt_finding::common::print_map, misc::Map};
use rand::Rng; use rand::Rng;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use termcolor::ColorSpec;
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
struct Block { pub(crate) struct Block {
size: Position, pub(crate) size: Position,
input: Vec<Interface>, pub(crate) input: Vec<Interface>,
output: Vec<Interface>, pub(crate) output: Vec<Interface>,
} }
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
struct Interface { pub(crate) struct Interface {
offset: Position, pub(crate) offset: Position,
dir: Direction, pub(crate) dir: Direction,
} }
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
struct Connection { pub(crate) struct Connection {
startblock: usize, pub(crate) startblock: usize,
startpoint: usize, pub(crate) startpoint: usize,
endblock: usize, pub(crate) endblock: usize,
endpoint: usize, pub(crate) endpoint: usize,
} }
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
pub struct Problem { pub struct Problem {
size: Position, pub(crate) size: Position,
blocks: Vec<Block>, pub(crate) blocks: Vec<Block>,
connections: Vec<Connection>, pub(crate) connections: Vec<Connection>,
} }
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
@ -39,8 +36,8 @@ pub struct BlockHandle(usize);
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Layout<'a> { pub struct Layout<'a> {
problem: &'a Problem, pub(crate) problem: &'a Problem,
blocks: Vec<(Position, Direction)>, pub(crate) blocks: Vec<(Position, Direction)>,
} }
impl Problem { impl Problem {
@ -164,7 +161,7 @@ impl Layout<'_> {
&& npos1.y + nsize1.y > npos2.y && npos1.y + nsize1.y > npos2.y
} }
fn normalize_pos(block: (&Block, Position, Direction)) -> (Position, Position) { pub(crate) fn normalize_pos(block: (&Block, Position, Direction)) -> (Position, Position) {
let npos = match block.2 { let npos = match block.2 {
Direction::Up => block.1, Direction::Up => block.1,
Direction::Right => block.1.in_direction(&Direction::Left, block.0.size.y - 1), Direction::Right => block.1.in_direction(&Direction::Left, block.0.size.y - 1),
@ -203,7 +200,7 @@ impl Layout<'_> {
sum sum
} }
fn transform(pos: Position, dir: Direction, offset: Position) -> Position { pub(crate) fn transform(pos: Position, dir: Direction, offset: Position) -> Position {
match dir { match dir {
Direction::Up => pos + offset, Direction::Up => pos + offset,
Direction::Right => pos + Position::new(-offset.y, offset.x), Direction::Right => pos + Position::new(-offset.y, offset.x),
@ -211,6 +208,24 @@ impl Layout<'_> {
Direction::Left => pos + Position::new(offset.y, -offset.x), Direction::Left => pos + Position::new(offset.y, -offset.x),
} }
} }
pub(crate) fn rotate(dir: Direction, rot: Direction) -> Direction {
match (rot, dir) {
(Direction::Up, _) => dir,
(Direction::Right, Direction::Up) => Direction::Right,
(Direction::Right, Direction::Right) => Direction::Down,
(Direction::Right, Direction::Down) => Direction::Left,
(Direction::Right, Direction::Left) => Direction::Up,
(Direction::Down, Direction::Up) => Direction::Down,
(Direction::Down, Direction::Right) => Direction::Left,
(Direction::Down, Direction::Down) => Direction::Up,
(Direction::Down, Direction::Left) => Direction::Right,
(Direction::Left, Direction::Up) => Direction::Left,
(Direction::Left, Direction::Right) => Direction::Up,
(Direction::Left, Direction::Down) => Direction::Right,
(Direction::Left, Direction::Left) => Direction::Down,
}
}
} }
impl<'a> Visualize for Layout<'a> { impl<'a> Visualize for Layout<'a> {