Refactor common types.
This commit is contained in:
parent
f284b692cc
commit
48419b4674
14 changed files with 376 additions and 250 deletions
42
Cargo.lock
generated
42
Cargo.lock
generated
|
|
@ -272,6 +272,12 @@ version = "1.10.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a"
|
checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "equivalent"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "factorio_blueprint"
|
name = "factorio_blueprint"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
|
@ -283,6 +289,7 @@ dependencies = [
|
||||||
"rand",
|
"rand",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"serde_yaml",
|
||||||
"termcolor",
|
"termcolor",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -313,6 +320,12 @@ version = "1.8.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1b43ede17f21864e81be2fa654110bf1e793774238d86ef8555c37e6519c0403"
|
checksum = "1b43ede17f21864e81be2fa654110bf1e793774238d86ef8555c37e6519c0403"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown"
|
||||||
|
version = "0.14.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "heck"
|
name = "heck"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
|
|
@ -328,6 +341,16 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "indexmap"
|
||||||
|
version = "2.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c"
|
||||||
|
dependencies = [
|
||||||
|
"equivalent",
|
||||||
|
"hashbrown",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itertools"
|
name = "itertools"
|
||||||
version = "0.10.5"
|
version = "0.10.5"
|
||||||
|
|
@ -596,6 +619,19 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_yaml"
|
||||||
|
version = "0.9.34+deprecated"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47"
|
||||||
|
dependencies = [
|
||||||
|
"indexmap",
|
||||||
|
"itoa",
|
||||||
|
"ryu",
|
||||||
|
"serde",
|
||||||
|
"unsafe-libyaml",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strsim"
|
name = "strsim"
|
||||||
version = "0.11.0"
|
version = "0.11.0"
|
||||||
|
|
@ -653,6 +689,12 @@ version = "0.1.11"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85"
|
checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unsafe-libyaml"
|
||||||
|
version = "0.2.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "utf8parse"
|
name = "utf8parse"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
|
|
|
||||||
|
|
@ -22,4 +22,5 @@ flate2 = "1.0.28"
|
||||||
rand = { version = "0.8.5", features = ["small_rng"] }
|
rand = { version = "0.8.5", features = ["small_rng"] }
|
||||||
serde = { version = "1.0.192", features = ["derive"] }
|
serde = { version = "1.0.192", features = ["derive"] }
|
||||||
serde_json = "1.0.108"
|
serde_json = "1.0.108"
|
||||||
|
serde_yaml = "0.9.34"
|
||||||
termcolor = "1.4.1"
|
termcolor = "1.4.1"
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,23 @@
|
||||||
use factorio_blueprint::{
|
use factorio_blueprint::layout::Layout;
|
||||||
belt_finding::common::Position,
|
|
||||||
layout::{Layout, Problem},
|
|
||||||
};
|
|
||||||
use rand::SeedableRng;
|
use rand::SeedableRng;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut p = Problem::new(Position::new(10, 10));
|
// let mut p = Problem::new(Position::new(10, 10));
|
||||||
|
|
||||||
let b1 = p.add_block(Position::new(3, 2));
|
// let b1 = p.add_block(Position::new(3, 2));
|
||||||
let b2 = p.add_block(Position::new(5, 2));
|
// let b2 = p.add_block(Position::new(5, 2));
|
||||||
let b3 = p.add_block(Position::new(5, 7));
|
// let b3 = p.add_block(Position::new(5, 7));
|
||||||
|
|
||||||
p.add_connection(b1, Position::new(0, 0), b2, Position::new(0, 0));
|
// p.add_connection(b1, Position::new(1, 0), b2, Position::new(1, 0));
|
||||||
p.add_connection(b2, Position::new(3, 1), b3, Position::new(4, 6));
|
// p.add_connection(b2, Position::new(3, 1), b3, Position::new(4, 6));
|
||||||
|
|
||||||
for i in 0..10 {
|
let file = std::fs::File::open("layout.yml").unwrap();
|
||||||
|
|
||||||
|
let p = serde_yaml::from_reader(file).unwrap();
|
||||||
|
|
||||||
|
dbg!(&p);
|
||||||
|
|
||||||
|
for i in 0..1 {
|
||||||
let mut rng = rand::rngs::SmallRng::seed_from_u64(i);
|
let mut rng = rand::rngs::SmallRng::seed_from_u64(i);
|
||||||
|
|
||||||
let l = Layout::new(&p, &mut rng);
|
let l = Layout::new(&p, &mut rng);
|
||||||
|
|
|
||||||
40
layout.yml
Normal file
40
layout.yml
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
size:
|
||||||
|
x: 10
|
||||||
|
y: 10
|
||||||
|
blocks:
|
||||||
|
- size:
|
||||||
|
x: 3
|
||||||
|
y: 2
|
||||||
|
input:
|
||||||
|
- offset:
|
||||||
|
x: 1
|
||||||
|
y: 1
|
||||||
|
dir: Down
|
||||||
|
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: Left
|
||||||
|
output:
|
||||||
|
connections:
|
||||||
|
- startblock: 1
|
||||||
|
startpoint: 0
|
||||||
|
endblock: 0
|
||||||
|
endpoint: 0
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
use super::{
|
use super::{
|
||||||
common::{print_map, Direction, PathField, PositionType},
|
common::{print_map, PathField},
|
||||||
Position, COLORS,
|
Position,
|
||||||
};
|
};
|
||||||
use crate::misc::Map;
|
use crate::misc::Map;
|
||||||
|
use crate::prelude::*;
|
||||||
use termcolor::ColorSpec;
|
use termcolor::ColorSpec;
|
||||||
|
|
||||||
#[derive(Default, Debug, Clone)]
|
#[derive(Default, Debug, Clone)]
|
||||||
|
|
@ -651,7 +652,7 @@ impl Bruteforce {
|
||||||
let _ = print_map(self.map.width as i32, self.map.height as i32, |x, y| {
|
let _ = print_map(self.map.width as i32, self.map.height as i32, |x, y| {
|
||||||
if let Some((i, c)) = m.get(x as usize, y as usize) {
|
if let Some((i, c)) = m.get(x as usize, y as usize) {
|
||||||
let mut color = ColorSpec::new();
|
let mut color = ColorSpec::new();
|
||||||
color.set_fg(Some(COLORS[*i]));
|
color.set_fg(Some(crate::common::color::COLORS[*i]));
|
||||||
(color, *c)
|
(color, *c)
|
||||||
} else if self.map.get(x as usize, y as usize).blocked {
|
} else if self.map.get(x as usize, y as usize).blocked {
|
||||||
(ColorSpec::new(), "#")
|
(ColorSpec::new(), "#")
|
||||||
|
|
|
||||||
|
|
@ -1,170 +1,8 @@
|
||||||
use core::panic;
|
|
||||||
use std::io::{self, Write};
|
use std::io::{self, Write};
|
||||||
|
|
||||||
use rand::prelude::Distribution;
|
|
||||||
use termcolor::{ColorSpec, StandardStream, WriteColor};
|
use termcolor::{ColorSpec, StandardStream, WriteColor};
|
||||||
|
|
||||||
pub type PositionType = i32;
|
use crate::prelude::*;
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
|
|
||||||
pub enum Direction {
|
|
||||||
Up,
|
|
||||||
Right,
|
|
||||||
Down,
|
|
||||||
Left,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Direction {
|
|
||||||
pub fn from_neighbors(pos: &Position, neighbor: &Position) -> Self {
|
|
||||||
let x_diff = pos.x as i64 - neighbor.x as i64;
|
|
||||||
let y_diff = pos.y as i64 - neighbor.y as i64;
|
|
||||||
|
|
||||||
match (x_diff, y_diff) {
|
|
||||||
(1, 0) => Direction::Left,
|
|
||||||
(0, 1) => Direction::Up,
|
|
||||||
(-1, 0) => Direction::Right,
|
|
||||||
(0, -1) => Direction::Down,
|
|
||||||
_ => {
|
|
||||||
panic!("Positions are not neighbors.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn vertical(&self) -> bool {
|
|
||||||
match self {
|
|
||||||
Direction::Up => true,
|
|
||||||
Direction::Right => false,
|
|
||||||
Direction::Down => true,
|
|
||||||
Direction::Left => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn horizontal(&self) -> bool {
|
|
||||||
!self.vertical()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn reverse(&self) -> Self {
|
|
||||||
match self {
|
|
||||||
Direction::Up => Direction::Down,
|
|
||||||
Direction::Right => Direction::Left,
|
|
||||||
Direction::Down => Direction::Up,
|
|
||||||
Direction::Left => Direction::Right,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn clockwise(&self) -> Self {
|
|
||||||
match self {
|
|
||||||
Direction::Up => Direction::Right,
|
|
||||||
Direction::Right => Direction::Down,
|
|
||||||
Direction::Down => Direction::Left,
|
|
||||||
Direction::Left => Direction::Up,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn counter_clockwise(&self) -> Self {
|
|
||||||
match self {
|
|
||||||
Direction::Up => Direction::Left,
|
|
||||||
Direction::Right => Direction::Up,
|
|
||||||
Direction::Down => Direction::Right,
|
|
||||||
Direction::Left => Direction::Down,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_index(&self) -> u8 {
|
|
||||||
match self {
|
|
||||||
Direction::Up => 0,
|
|
||||||
Direction::Right => 1,
|
|
||||||
Direction::Down => 2,
|
|
||||||
Direction::Left => 3,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn from_index(i: u8) -> Self {
|
|
||||||
match i {
|
|
||||||
0 => Direction::Up,
|
|
||||||
1 => Direction::Right,
|
|
||||||
2 => Direction::Down,
|
|
||||||
3 => Direction::Left,
|
|
||||||
_ => panic!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Distribution<Direction> for rand::distributions::Standard {
|
|
||||||
fn sample<R: rand::Rng + ?Sized>(&self, rng: &mut R) -> Direction {
|
|
||||||
let a = [
|
|
||||||
Direction::Up,
|
|
||||||
Direction::Right,
|
|
||||||
Direction::Down,
|
|
||||||
Direction::Left,
|
|
||||||
];
|
|
||||||
let r = rng.gen_range(0..4);
|
|
||||||
a[r]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
|
||||||
pub struct Position {
|
|
||||||
pub x: PositionType,
|
|
||||||
pub y: PositionType,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
|
||||||
pub struct Dimension {
|
|
||||||
pub width: usize,
|
|
||||||
pub height: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Position {
|
|
||||||
pub fn new(x: PositionType, y: PositionType) -> Self {
|
|
||||||
Self { x, y }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn in_direction(&self, dir: &Direction, len: PositionType) -> Position {
|
|
||||||
match dir {
|
|
||||||
Direction::Up => Position::new(self.x, self.y - len),
|
|
||||||
Direction::Right => Position::new(self.x + len, self.y),
|
|
||||||
Direction::Down => Position::new(self.x, self.y + len),
|
|
||||||
Direction::Left => Position::new(self.x - len, self.y),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn in_range(&self, min: &Position, max: &Position) -> Option<&Position> {
|
|
||||||
if self.x < min.x {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
if self.x >= max.x {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
if self.y < min.y {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
if self.y >= max.y {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
Some(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl std::ops::Add for Position {
|
|
||||||
type Output = Position;
|
|
||||||
|
|
||||||
fn add(mut self, rhs: Self) -> Self::Output {
|
|
||||||
self.x += rhs.x;
|
|
||||||
self.y += rhs.y;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl std::ops::Sub for Position {
|
|
||||||
type Output = Position;
|
|
||||||
|
|
||||||
fn sub(mut self, rhs: Self) -> Self::Output {
|
|
||||||
self.x -= rhs.x;
|
|
||||||
self.y -= rhs.y;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Copy)]
|
#[derive(Clone, Debug, Copy)]
|
||||||
pub enum PathField {
|
pub enum PathField {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
use super::{
|
use super::{
|
||||||
common::{print_map, Direction, PathField, Position, PositionType},
|
common::{print_map, PathField},
|
||||||
Problem, COLORS,
|
Problem,
|
||||||
};
|
};
|
||||||
|
use crate::prelude::*;
|
||||||
use crate::{belt_finding::brute_force::BruteforceBuilder, misc::Map};
|
use crate::{belt_finding::brute_force::BruteforceBuilder, misc::Map};
|
||||||
use std::ops::RangeInclusive;
|
use std::ops::RangeInclusive;
|
||||||
use termcolor::ColorSpec;
|
use termcolor::ColorSpec;
|
||||||
|
|
@ -520,7 +521,7 @@ impl ConflictAvoidance {
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some((i, c)) = m.get(x as usize, y as usize) {
|
if let Some((i, c)) = m.get(x as usize, y as usize) {
|
||||||
color.set_fg(Some(COLORS[*i]));
|
color.set_fg(Some(crate::common::color::COLORS[*i]));
|
||||||
(color, c)
|
(color, c)
|
||||||
} else if self.map.get(x as usize, y as usize).blocked {
|
} else if self.map.get(x as usize, y as usize).blocked {
|
||||||
(color, "#")
|
(color, "#")
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,13 @@
|
||||||
|
use crate::common::color::COLORS;
|
||||||
use crate::graph::wheighted_graph::WheightedGraph;
|
use crate::graph::wheighted_graph::WheightedGraph;
|
||||||
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,
|
||||||
};
|
};
|
||||||
use std::ops::Index;
|
use termcolor::ColorSpec;
|
||||||
use termcolor::{Color, ColorSpec};
|
|
||||||
|
|
||||||
use self::common::{print_map, Direction, Position, PositionType};
|
use self::common::print_map;
|
||||||
|
use crate::prelude::*;
|
||||||
|
|
||||||
pub mod brute_force;
|
pub mod brute_force;
|
||||||
pub mod common;
|
pub mod common;
|
||||||
|
|
@ -128,25 +129,6 @@ impl Problem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub static COLORS: Cyclic<Color, 6> = Cyclic([
|
|
||||||
Color::Red,
|
|
||||||
Color::Green,
|
|
||||||
Color::Yellow,
|
|
||||||
Color::Blue,
|
|
||||||
Color::Magenta,
|
|
||||||
Color::Cyan,
|
|
||||||
]);
|
|
||||||
|
|
||||||
pub struct Cyclic<T, const N: usize>([T; N]);
|
|
||||||
|
|
||||||
impl<T, const N: usize> Index<usize> for Cyclic<T, N> {
|
|
||||||
type Output = T;
|
|
||||||
|
|
||||||
fn index(&self, index: usize) -> &Self::Output {
|
|
||||||
&self.0[index % N]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct MapInternal<'a> {
|
struct MapInternal<'a> {
|
||||||
map: &'a Map<Field>,
|
map: &'a Map<Field>,
|
||||||
end: (Position, Direction),
|
end: (Position, Direction),
|
||||||
|
|
@ -215,10 +197,8 @@ impl Problem {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod problems {
|
pub mod problems {
|
||||||
use super::{
|
use super::Problem;
|
||||||
common::{Direction, Position},
|
use crate::prelude::*;
|
||||||
Problem,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub fn simple() -> Problem {
|
pub fn simple() -> Problem {
|
||||||
let mut p = Problem::new(5, 3);
|
let mut p = Problem::new(5, 3);
|
||||||
|
|
|
||||||
21
src/common/color.rs
Normal file
21
src/common/color.rs
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
use std::ops::Index;
|
||||||
|
use termcolor::Color;
|
||||||
|
|
||||||
|
pub static COLORS: Cyclic<Color, 6> = Cyclic([
|
||||||
|
Color::Red,
|
||||||
|
Color::Green,
|
||||||
|
Color::Yellow,
|
||||||
|
Color::Blue,
|
||||||
|
Color::Magenta,
|
||||||
|
Color::Cyan,
|
||||||
|
]);
|
||||||
|
|
||||||
|
pub struct Cyclic<T, const N: usize>([T; N]);
|
||||||
|
|
||||||
|
impl<T, const N: usize> Index<usize> for Cyclic<T, N> {
|
||||||
|
type Output = T;
|
||||||
|
|
||||||
|
fn index(&self, index: usize) -> &Self::Output {
|
||||||
|
&self.0[index % N]
|
||||||
|
}
|
||||||
|
}
|
||||||
99
src/common/direction.rs
Normal file
99
src/common/direction.rs
Normal file
|
|
@ -0,0 +1,99 @@
|
||||||
|
use crate::prelude::*;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Deserialize, Serialize)]
|
||||||
|
pub enum Direction {
|
||||||
|
Up,
|
||||||
|
Right,
|
||||||
|
Down,
|
||||||
|
Left,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Direction {
|
||||||
|
pub fn from_neighbors(pos: &Position, neighbor: &Position) -> Self {
|
||||||
|
let x_diff = pos.x as i64 - neighbor.x as i64;
|
||||||
|
let y_diff = pos.y as i64 - neighbor.y as i64;
|
||||||
|
|
||||||
|
match (x_diff, y_diff) {
|
||||||
|
(1, 0) => Direction::Left,
|
||||||
|
(0, 1) => Direction::Up,
|
||||||
|
(-1, 0) => Direction::Right,
|
||||||
|
(0, -1) => Direction::Down,
|
||||||
|
_ => {
|
||||||
|
panic!("Positions are not neighbors.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn vertical(&self) -> bool {
|
||||||
|
match self {
|
||||||
|
Direction::Up => true,
|
||||||
|
Direction::Right => false,
|
||||||
|
Direction::Down => true,
|
||||||
|
Direction::Left => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn horizontal(&self) -> bool {
|
||||||
|
!self.vertical()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reverse(&self) -> Self {
|
||||||
|
match self {
|
||||||
|
Direction::Up => Direction::Down,
|
||||||
|
Direction::Right => Direction::Left,
|
||||||
|
Direction::Down => Direction::Up,
|
||||||
|
Direction::Left => Direction::Right,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn clockwise(&self) -> Self {
|
||||||
|
match self {
|
||||||
|
Direction::Up => Direction::Right,
|
||||||
|
Direction::Right => Direction::Down,
|
||||||
|
Direction::Down => Direction::Left,
|
||||||
|
Direction::Left => Direction::Up,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn counter_clockwise(&self) -> Self {
|
||||||
|
match self {
|
||||||
|
Direction::Up => Direction::Left,
|
||||||
|
Direction::Right => Direction::Up,
|
||||||
|
Direction::Down => Direction::Right,
|
||||||
|
Direction::Left => Direction::Down,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_index(&self) -> u8 {
|
||||||
|
match self {
|
||||||
|
Direction::Up => 0,
|
||||||
|
Direction::Right => 1,
|
||||||
|
Direction::Down => 2,
|
||||||
|
Direction::Left => 3,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_index(i: u8) -> Self {
|
||||||
|
match i {
|
||||||
|
0 => Direction::Up,
|
||||||
|
1 => Direction::Right,
|
||||||
|
2 => Direction::Down,
|
||||||
|
3 => Direction::Left,
|
||||||
|
_ => panic!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl rand::prelude::Distribution<Direction> for rand::distributions::Standard {
|
||||||
|
fn sample<R: rand::Rng + ?Sized>(&self, rng: &mut R) -> Direction {
|
||||||
|
let a = [
|
||||||
|
Direction::Up,
|
||||||
|
Direction::Right,
|
||||||
|
Direction::Down,
|
||||||
|
Direction::Left,
|
||||||
|
];
|
||||||
|
let r = rng.gen_range(0..4);
|
||||||
|
a[r]
|
||||||
|
}
|
||||||
|
}
|
||||||
3
src/common/mod.rs
Normal file
3
src/common/mod.rs
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
pub mod color;
|
||||||
|
pub mod direction;
|
||||||
|
pub mod position;
|
||||||
67
src/common/position.rs
Normal file
67
src/common/position.rs
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
use crate::prelude::*;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
pub type PositionType = i32;
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)]
|
||||||
|
pub struct Position {
|
||||||
|
pub x: PositionType,
|
||||||
|
pub y: PositionType,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||||
|
pub struct Dimension {
|
||||||
|
pub width: usize,
|
||||||
|
pub height: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Position {
|
||||||
|
pub fn new(x: PositionType, y: PositionType) -> Self {
|
||||||
|
Self { x, y }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn in_direction(&self, dir: &Direction, len: PositionType) -> Position {
|
||||||
|
match dir {
|
||||||
|
Direction::Up => Position::new(self.x, self.y - len),
|
||||||
|
Direction::Right => Position::new(self.x + len, self.y),
|
||||||
|
Direction::Down => Position::new(self.x, self.y + len),
|
||||||
|
Direction::Left => Position::new(self.x - len, self.y),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn in_range(&self, min: &Position, max: &Position) -> Option<&Position> {
|
||||||
|
if self.x < min.x {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
if self.x >= max.x {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
if self.y < min.y {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
if self.y >= max.y {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
Some(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::ops::Add for Position {
|
||||||
|
type Output = Position;
|
||||||
|
|
||||||
|
fn add(mut self, rhs: Self) -> Self::Output {
|
||||||
|
self.x += rhs.x;
|
||||||
|
self.y += rhs.y;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::ops::Sub for Position {
|
||||||
|
type Output = Position;
|
||||||
|
|
||||||
|
fn sub(mut self, rhs: Self) -> Self::Output {
|
||||||
|
self.x -= rhs.x;
|
||||||
|
self.y -= rhs.y;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,32 +1,36 @@
|
||||||
use crate::{
|
use crate::prelude::*;
|
||||||
belt_finding::{
|
use crate::{belt_finding::common::print_map, misc::Map};
|
||||||
common::{print_map, Direction, Position},
|
|
||||||
COLORS,
|
|
||||||
},
|
|
||||||
misc::Map,
|
|
||||||
};
|
|
||||||
|
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
use termcolor::ColorSpec;
|
use termcolor::ColorSpec;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
struct Block {
|
struct Block {
|
||||||
size: Position,
|
size: Position,
|
||||||
input: Vec<Interface>,
|
input: Vec<Interface>,
|
||||||
output: Vec<Interface>,
|
output: Vec<Interface>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
struct Interface {
|
struct Interface {
|
||||||
offset: Position,
|
offset: Position,
|
||||||
// dir: Direction,
|
dir: Direction,
|
||||||
target: (usize, usize),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
struct Connection {
|
||||||
|
startblock: usize,
|
||||||
|
startpoint: usize,
|
||||||
|
endblock: usize,
|
||||||
|
endpoint: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct Problem {
|
pub struct Problem {
|
||||||
size: Position,
|
size: Position,
|
||||||
blocks: Vec<Block>,
|
blocks: Vec<Block>,
|
||||||
|
connections: Vec<Connection>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
|
@ -43,6 +47,7 @@ impl Problem {
|
||||||
Self {
|
Self {
|
||||||
size,
|
size,
|
||||||
blocks: Vec::new(),
|
blocks: Vec::new(),
|
||||||
|
connections: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -56,26 +61,26 @@ impl Problem {
|
||||||
BlockHandle(self.blocks.len() - 1)
|
BlockHandle(self.blocks.len() - 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_connection(
|
// pub fn add_connection(
|
||||||
&mut self,
|
// &mut self,
|
||||||
starthandle: BlockHandle,
|
// starthandle: BlockHandle,
|
||||||
startoffset: Position,
|
// startoffset: Position,
|
||||||
endhandle: BlockHandle,
|
// endhandle: BlockHandle,
|
||||||
endoffset: Position,
|
// endoffset: Position,
|
||||||
) {
|
// ) {
|
||||||
let startinterface = self.blocks[starthandle.0].output.len();
|
// let startinterface = self.blocks[starthandle.0].output.len();
|
||||||
let endinterface = self.blocks[endhandle.0].input.len();
|
// let endinterface = self.blocks[endhandle.0].input.len();
|
||||||
|
|
||||||
self.blocks[starthandle.0].output.push(Interface {
|
// self.blocks[starthandle.0].output.push(Interface {
|
||||||
offset: startoffset,
|
// offset: startoffset,
|
||||||
target: (endhandle.0, endinterface),
|
// target: (endhandle.0, endinterface),
|
||||||
});
|
// });
|
||||||
|
|
||||||
self.blocks[endhandle.0].input.push(Interface {
|
// self.blocks[endhandle.0].input.push(Interface {
|
||||||
offset: endoffset,
|
// offset: endoffset,
|
||||||
target: (starthandle.0, startinterface),
|
// target: (starthandle.0, startinterface),
|
||||||
})
|
// })
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Layout<'_> {
|
impl Layout<'_> {
|
||||||
|
|
@ -176,18 +181,21 @@ impl Layout<'_> {
|
||||||
|
|
||||||
pub fn score(&self) -> i32 {
|
pub fn score(&self) -> i32 {
|
||||||
let mut sum = 0;
|
let mut sum = 0;
|
||||||
for ((pos, dir), b) in self.blocks.iter().zip(self.problem.blocks.iter()) {
|
|
||||||
for i in &b.output {
|
for c in &self.problem.connections {
|
||||||
let startpos = Self::transform(*pos, *dir, i.offset);
|
let startpos = Self::transform(
|
||||||
|
self.blocks[c.startblock].0,
|
||||||
|
self.blocks[c.startblock].1,
|
||||||
|
self.problem.blocks[c.startblock].output[c.startpoint].offset,
|
||||||
|
);
|
||||||
let endpos = Self::transform(
|
let endpos = Self::transform(
|
||||||
self.blocks[i.target.0].0,
|
self.blocks[c.endblock].0,
|
||||||
self.blocks[i.target.0].1,
|
self.blocks[c.endblock].1,
|
||||||
self.problem.blocks[i.target.0].input[i.target.1].offset,
|
self.problem.blocks[c.endblock].input[c.endpoint].offset,
|
||||||
);
|
);
|
||||||
|
|
||||||
sum += (startpos.x - endpos.x).abs() + (startpos.y - endpos.y).abs();
|
sum += (startpos.x - endpos.x).abs() + (startpos.y - endpos.y).abs();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
sum
|
sum
|
||||||
}
|
}
|
||||||
|
|
@ -202,7 +210,7 @@ impl Layout<'_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print(&self) {
|
pub fn print(&self) {
|
||||||
let mut m: Map<Option<usize>> =
|
let mut m: Map<Option<(usize, &str)>> =
|
||||||
Map::new(self.problem.size.x as usize, self.problem.size.y as usize);
|
Map::new(self.problem.size.x as usize, self.problem.size.y as usize);
|
||||||
|
|
||||||
for (i, ((p, d), b)) in self
|
for (i, ((p, d), b)) in self
|
||||||
|
|
@ -215,16 +223,32 @@ impl Layout<'_> {
|
||||||
|
|
||||||
for x in npos.x..(npos.x + nsize.x) {
|
for x in npos.x..(npos.x + nsize.x) {
|
||||||
for y in npos.y..(npos.y + nsize.y) {
|
for y in npos.y..(npos.y + nsize.y) {
|
||||||
m.set(x as usize, y as usize, Some(i));
|
m.set(x as usize, y as usize, Some((i, "#")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let pos = Self::transform(*p, *d, Position::new(0, 0));
|
||||||
|
|
||||||
|
m.set(pos.x as usize, pos.y as usize, Some((i, "X")));
|
||||||
|
|
||||||
|
for input in &b.input {
|
||||||
|
let pos = Self::transform(*p, *d, input.offset);
|
||||||
|
|
||||||
|
m.set(pos.x as usize, pos.y as usize, Some((i, "i")));
|
||||||
|
}
|
||||||
|
|
||||||
|
for output in &b.output {
|
||||||
|
let pos = Self::transform(*p, *d, output.offset);
|
||||||
|
|
||||||
|
m.set(pos.x as usize, pos.y as usize, Some((i, "o")));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let _ = print_map(self.problem.size.x, self.problem.size.y, |x, y| {
|
let _ = print_map(self.problem.size.x, self.problem.size.y, |x, y| {
|
||||||
if let Some(i) = m.get(x as usize, y as usize) {
|
if let Some(i) = m.get(x as usize, y as usize) {
|
||||||
let mut color = ColorSpec::new();
|
let mut color = ColorSpec::new();
|
||||||
color.set_fg(Some(COLORS[*i]));
|
color.set_fg(Some(crate::common::color::COLORS[i.0]));
|
||||||
(color, "#")
|
(color, i.1)
|
||||||
} else {
|
} else {
|
||||||
(ColorSpec::new(), " ")
|
(ColorSpec::new(), " ")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,12 @@
|
||||||
pub mod belt_finding;
|
pub mod belt_finding;
|
||||||
pub mod blueprint;
|
pub mod blueprint;
|
||||||
|
pub mod common;
|
||||||
pub mod graph;
|
pub mod graph;
|
||||||
pub mod layout;
|
pub mod layout;
|
||||||
pub mod misc;
|
pub mod misc;
|
||||||
pub mod priority_queue;
|
pub mod priority_queue;
|
||||||
|
|
||||||
|
pub mod prelude {
|
||||||
|
pub use crate::common::direction::Direction;
|
||||||
|
pub use crate::common::position::{Position, PositionType};
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue