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"
|
||||
checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a"
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
||||
|
||||
[[package]]
|
||||
name = "factorio_blueprint"
|
||||
version = "0.1.0"
|
||||
|
|
@ -283,6 +289,7 @@ dependencies = [
|
|||
"rand",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_yaml",
|
||||
"termcolor",
|
||||
]
|
||||
|
||||
|
|
@ -313,6 +320,12 @@ version = "1.8.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b43ede17f21864e81be2fa654110bf1e793774238d86ef8555c37e6519c0403"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.14.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.5.0"
|
||||
|
|
@ -328,6 +341,16 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.10.5"
|
||||
|
|
@ -596,6 +619,19 @@ dependencies = [
|
|||
"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]]
|
||||
name = "strsim"
|
||||
version = "0.11.0"
|
||||
|
|
@ -653,6 +689,12 @@ version = "0.1.11"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85"
|
||||
|
||||
[[package]]
|
||||
name = "unsafe-libyaml"
|
||||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861"
|
||||
|
||||
[[package]]
|
||||
name = "utf8parse"
|
||||
version = "0.2.1"
|
||||
|
|
|
|||
|
|
@ -22,4 +22,5 @@ flate2 = "1.0.28"
|
|||
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"
|
||||
termcolor = "1.4.1"
|
||||
|
|
|
|||
|
|
@ -1,20 +1,23 @@
|
|||
use factorio_blueprint::{
|
||||
belt_finding::common::Position,
|
||||
layout::{Layout, Problem},
|
||||
};
|
||||
use factorio_blueprint::layout::Layout;
|
||||
use rand::SeedableRng;
|
||||
|
||||
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 b2 = p.add_block(Position::new(5, 2));
|
||||
let b3 = p.add_block(Position::new(5, 7));
|
||||
// let b1 = p.add_block(Position::new(3, 2));
|
||||
// let b2 = p.add_block(Position::new(5, 2));
|
||||
// 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(b2, Position::new(3, 1), b3, Position::new(4, 6));
|
||||
// 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));
|
||||
|
||||
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 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::{
|
||||
common::{print_map, Direction, PathField, PositionType},
|
||||
Position, COLORS,
|
||||
common::{print_map, PathField},
|
||||
Position,
|
||||
};
|
||||
use crate::misc::Map;
|
||||
use crate::prelude::*;
|
||||
use termcolor::ColorSpec;
|
||||
|
||||
#[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| {
|
||||
if let Some((i, c)) = m.get(x as usize, y as usize) {
|
||||
let mut color = ColorSpec::new();
|
||||
color.set_fg(Some(COLORS[*i]));
|
||||
color.set_fg(Some(crate::common::color::COLORS[*i]));
|
||||
(color, *c)
|
||||
} else if self.map.get(x as usize, y as usize).blocked {
|
||||
(ColorSpec::new(), "#")
|
||||
|
|
|
|||
|
|
@ -1,170 +1,8 @@
|
|||
use core::panic;
|
||||
use std::io::{self, Write};
|
||||
|
||||
use rand::prelude::Distribution;
|
||||
use termcolor::{ColorSpec, StandardStream, WriteColor};
|
||||
|
||||
pub type PositionType = i32;
|
||||
|
||||
#[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
|
||||
}
|
||||
}
|
||||
use crate::prelude::*;
|
||||
|
||||
#[derive(Clone, Debug, Copy)]
|
||||
pub enum PathField {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
use super::{
|
||||
common::{print_map, Direction, PathField, Position, PositionType},
|
||||
Problem, COLORS,
|
||||
common::{print_map, PathField},
|
||||
Problem,
|
||||
};
|
||||
use crate::prelude::*;
|
||||
use crate::{belt_finding::brute_force::BruteforceBuilder, misc::Map};
|
||||
use std::ops::RangeInclusive;
|
||||
use termcolor::ColorSpec;
|
||||
|
|
@ -520,7 +521,7 @@ impl ConflictAvoidance {
|
|||
}
|
||||
|
||||
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)
|
||||
} else if self.map.get(x as usize, y as usize).blocked {
|
||||
(color, "#")
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
use crate::common::color::COLORS;
|
||||
use crate::graph::wheighted_graph::WheightedGraph;
|
||||
use crate::misc::Map;
|
||||
use crate::{
|
||||
graph::wheighted_graph::shortest_path::dijkstra, priority_queue::fibonacci_heap::FibonacciHeap,
|
||||
};
|
||||
use std::ops::Index;
|
||||
use termcolor::{Color, ColorSpec};
|
||||
use termcolor::ColorSpec;
|
||||
|
||||
use self::common::{print_map, Direction, Position, PositionType};
|
||||
use self::common::print_map;
|
||||
use crate::prelude::*;
|
||||
|
||||
pub mod brute_force;
|
||||
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> {
|
||||
map: &'a Map<Field>,
|
||||
end: (Position, Direction),
|
||||
|
|
@ -215,10 +197,8 @@ impl Problem {
|
|||
}
|
||||
|
||||
pub mod problems {
|
||||
use super::{
|
||||
common::{Direction, Position},
|
||||
Problem,
|
||||
};
|
||||
use super::Problem;
|
||||
use crate::prelude::*;
|
||||
|
||||
pub fn simple() -> Problem {
|
||||
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::{
|
||||
belt_finding::{
|
||||
common::{print_map, Direction, Position},
|
||||
COLORS,
|
||||
},
|
||||
misc::Map,
|
||||
};
|
||||
use crate::prelude::*;
|
||||
use crate::{belt_finding::common::print_map, misc::Map};
|
||||
|
||||
use rand::Rng;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use termcolor::ColorSpec;
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct Block {
|
||||
size: Position,
|
||||
input: Vec<Interface>,
|
||||
output: Vec<Interface>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct Interface {
|
||||
offset: Position,
|
||||
// dir: Direction,
|
||||
target: (usize, usize),
|
||||
dir: Direction,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct Connection {
|
||||
startblock: usize,
|
||||
startpoint: usize,
|
||||
endblock: usize,
|
||||
endpoint: usize,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct Problem {
|
||||
size: Position,
|
||||
blocks: Vec<Block>,
|
||||
connections: Vec<Connection>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
|
|
@ -43,6 +47,7 @@ impl Problem {
|
|||
Self {
|
||||
size,
|
||||
blocks: Vec::new(),
|
||||
connections: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -56,26 +61,26 @@ impl Problem {
|
|||
BlockHandle(self.blocks.len() - 1)
|
||||
}
|
||||
|
||||
pub fn add_connection(
|
||||
&mut self,
|
||||
starthandle: BlockHandle,
|
||||
startoffset: Position,
|
||||
endhandle: BlockHandle,
|
||||
endoffset: Position,
|
||||
) {
|
||||
let startinterface = self.blocks[starthandle.0].output.len();
|
||||
let endinterface = self.blocks[endhandle.0].input.len();
|
||||
// pub fn add_connection(
|
||||
// &mut self,
|
||||
// starthandle: BlockHandle,
|
||||
// startoffset: Position,
|
||||
// endhandle: BlockHandle,
|
||||
// endoffset: Position,
|
||||
// ) {
|
||||
// let startinterface = self.blocks[starthandle.0].output.len();
|
||||
// let endinterface = self.blocks[endhandle.0].input.len();
|
||||
|
||||
self.blocks[starthandle.0].output.push(Interface {
|
||||
offset: startoffset,
|
||||
target: (endhandle.0, endinterface),
|
||||
});
|
||||
// self.blocks[starthandle.0].output.push(Interface {
|
||||
// offset: startoffset,
|
||||
// target: (endhandle.0, endinterface),
|
||||
// });
|
||||
|
||||
self.blocks[endhandle.0].input.push(Interface {
|
||||
offset: endoffset,
|
||||
target: (starthandle.0, startinterface),
|
||||
})
|
||||
}
|
||||
// self.blocks[endhandle.0].input.push(Interface {
|
||||
// offset: endoffset,
|
||||
// target: (starthandle.0, startinterface),
|
||||
// })
|
||||
// }
|
||||
}
|
||||
|
||||
impl Layout<'_> {
|
||||
|
|
@ -176,17 +181,20 @@ impl Layout<'_> {
|
|||
|
||||
pub fn score(&self) -> i32 {
|
||||
let mut sum = 0;
|
||||
for ((pos, dir), b) in self.blocks.iter().zip(self.problem.blocks.iter()) {
|
||||
for i in &b.output {
|
||||
let startpos = Self::transform(*pos, *dir, i.offset);
|
||||
let endpos = Self::transform(
|
||||
self.blocks[i.target.0].0,
|
||||
self.blocks[i.target.0].1,
|
||||
self.problem.blocks[i.target.0].input[i.target.1].offset,
|
||||
);
|
||||
|
||||
sum += (startpos.x - endpos.x).abs() + (startpos.y - endpos.y).abs();
|
||||
}
|
||||
for c in &self.problem.connections {
|
||||
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(
|
||||
self.blocks[c.endblock].0,
|
||||
self.blocks[c.endblock].1,
|
||||
self.problem.blocks[c.endblock].input[c.endpoint].offset,
|
||||
);
|
||||
|
||||
sum += (startpos.x - endpos.x).abs() + (startpos.y - endpos.y).abs();
|
||||
}
|
||||
|
||||
sum
|
||||
|
|
@ -202,7 +210,7 @@ impl Layout<'_> {
|
|||
}
|
||||
|
||||
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);
|
||||
|
||||
for (i, ((p, d), b)) in self
|
||||
|
|
@ -215,16 +223,32 @@ impl Layout<'_> {
|
|||
|
||||
for x in npos.x..(npos.x + nsize.x) {
|
||||
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| {
|
||||
if let Some(i) = m.get(x as usize, y as usize) {
|
||||
let mut color = ColorSpec::new();
|
||||
color.set_fg(Some(COLORS[*i]));
|
||||
(color, "#")
|
||||
color.set_fg(Some(crate::common::color::COLORS[i.0]));
|
||||
(color, i.1)
|
||||
} else {
|
||||
(ColorSpec::new(), " ")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,12 @@
|
|||
pub mod belt_finding;
|
||||
pub mod blueprint;
|
||||
pub mod common;
|
||||
pub mod graph;
|
||||
pub mod layout;
|
||||
pub mod misc;
|
||||
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