Initial layout implementation.
This commit is contained in:
parent
1596bf180d
commit
f284b692cc
7 changed files with 374 additions and 6 deletions
88
Cargo.lock
generated
88
Cargo.lock
generated
|
|
@ -100,6 +100,12 @@ version = "3.15.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa"
|
checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "byteorder"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cast"
|
name = "cast"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
|
|
@ -274,6 +280,7 @@ dependencies = [
|
||||||
"clap 4.5.3",
|
"clap 4.5.3",
|
||||||
"criterion",
|
"criterion",
|
||||||
"flate2",
|
"flate2",
|
||||||
|
"rand",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"termcolor",
|
"termcolor",
|
||||||
|
|
@ -289,6 +296,17 @@ dependencies = [
|
||||||
"miniz_oxide",
|
"miniz_oxide",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "getrandom"
|
||||||
|
version = "0.2.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"wasi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "half"
|
name = "half"
|
||||||
version = "1.8.3"
|
version = "1.8.3"
|
||||||
|
|
@ -342,9 +360,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.153"
|
version = "0.2.158"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
|
checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "log"
|
name = "log"
|
||||||
|
|
@ -416,6 +434,15 @@ dependencies = [
|
||||||
"plotters-backend",
|
"plotters-backend",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ppv-lite86"
|
||||||
|
version = "0.2.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
|
||||||
|
dependencies = [
|
||||||
|
"zerocopy",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.79"
|
version = "1.0.79"
|
||||||
|
|
@ -434,6 +461,36 @@ dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand"
|
||||||
|
version = "0.8.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"rand_chacha",
|
||||||
|
"rand_core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_chacha"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||||
|
dependencies = [
|
||||||
|
"ppv-lite86",
|
||||||
|
"rand_core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_core"
|
||||||
|
version = "0.6.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rayon"
|
name = "rayon"
|
||||||
version = "1.9.0"
|
version = "1.9.0"
|
||||||
|
|
@ -612,6 +669,12 @@ dependencies = [
|
||||||
"winapi-util",
|
"winapi-util",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasi"
|
||||||
|
version = "0.11.0+wasi-snapshot-preview1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen"
|
name = "wasm-bindgen"
|
||||||
version = "0.2.92"
|
version = "0.2.92"
|
||||||
|
|
@ -772,3 +835,24 @@ name = "windows_x86_64_msvc"
|
||||||
version = "0.52.4"
|
version = "0.52.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8"
|
checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zerocopy"
|
||||||
|
version = "0.7.35"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
|
||||||
|
dependencies = [
|
||||||
|
"byteorder",
|
||||||
|
"zerocopy-derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zerocopy-derive"
|
||||||
|
version = "0.7.35"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ harness = false
|
||||||
base64 = "0.21.5"
|
base64 = "0.21.5"
|
||||||
clap = { version = "4.4.8", features = ["derive"] }
|
clap = { version = "4.4.8", features = ["derive"] }
|
||||||
flate2 = "1.0.28"
|
flate2 = "1.0.28"
|
||||||
|
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"
|
||||||
termcolor = "1.4.1"
|
termcolor = "1.4.1"
|
||||||
|
|
|
||||||
25
examples/layout.rs
Normal file
25
examples/layout.rs
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
use factorio_blueprint::{
|
||||||
|
belt_finding::common::Position,
|
||||||
|
layout::{Layout, Problem},
|
||||||
|
};
|
||||||
|
use rand::SeedableRng;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
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));
|
||||||
|
|
||||||
|
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));
|
||||||
|
|
||||||
|
for i in 0..10 {
|
||||||
|
let mut rng = rand::rngs::SmallRng::seed_from_u64(i);
|
||||||
|
|
||||||
|
let l = Layout::new(&p, &mut rng);
|
||||||
|
|
||||||
|
println!("Seed: {i}, Score {}", l.score());
|
||||||
|
l.print();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
use core::panic;
|
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;
|
pub type PositionType = i32;
|
||||||
|
|
@ -89,6 +90,19 @@ impl Direction {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||||
pub struct Position {
|
pub struct Position {
|
||||||
pub x: PositionType,
|
pub x: PositionType,
|
||||||
|
|
@ -132,6 +146,16 @@ impl Position {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 {
|
impl std::ops::Sub for Position {
|
||||||
type Output = Position;
|
type Output = Position;
|
||||||
|
|
||||||
|
|
@ -208,8 +232,8 @@ where
|
||||||
{
|
{
|
||||||
let stdout = &mut StandardStream::stdout(termcolor::ColorChoice::Always);
|
let stdout = &mut StandardStream::stdout(termcolor::ColorChoice::Always);
|
||||||
|
|
||||||
let width_digits = width.ilog10() + 1;
|
let width_digits = (width - 1).ilog10() + 1;
|
||||||
let height_digits = height.ilog10() + 1;
|
let height_digits = (height - 1).ilog10() + 1;
|
||||||
|
|
||||||
// print header
|
// print header
|
||||||
for i in 0..width_digits {
|
for i in 0..width_digits {
|
||||||
|
|
|
||||||
|
|
@ -128,7 +128,7 @@ impl Problem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static COLORS: Cyclic<Color, 6> = Cyclic([
|
pub static COLORS: Cyclic<Color, 6> = Cyclic([
|
||||||
Color::Red,
|
Color::Red,
|
||||||
Color::Green,
|
Color::Green,
|
||||||
Color::Yellow,
|
Color::Yellow,
|
||||||
|
|
@ -137,7 +137,7 @@ static COLORS: Cyclic<Color, 6> = Cyclic([
|
||||||
Color::Cyan,
|
Color::Cyan,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
struct Cyclic<T, const N: usize>([T; N]);
|
pub struct Cyclic<T, const N: usize>([T; N]);
|
||||||
|
|
||||||
impl<T, const N: usize> Index<usize> for Cyclic<T, N> {
|
impl<T, const N: usize> Index<usize> for Cyclic<T, N> {
|
||||||
type Output = T;
|
type Output = T;
|
||||||
|
|
|
||||||
233
src/layout/mod.rs
Normal file
233
src/layout/mod.rs
Normal file
|
|
@ -0,0 +1,233 @@
|
||||||
|
use crate::{
|
||||||
|
belt_finding::{
|
||||||
|
common::{print_map, Direction, Position},
|
||||||
|
COLORS,
|
||||||
|
},
|
||||||
|
misc::Map,
|
||||||
|
};
|
||||||
|
|
||||||
|
use rand::Rng;
|
||||||
|
use termcolor::ColorSpec;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Block {
|
||||||
|
size: Position,
|
||||||
|
input: Vec<Interface>,
|
||||||
|
output: Vec<Interface>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Interface {
|
||||||
|
offset: Position,
|
||||||
|
// dir: Direction,
|
||||||
|
target: (usize, usize),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Problem {
|
||||||
|
size: Position,
|
||||||
|
blocks: Vec<Block>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub struct BlockHandle(usize);
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Layout<'a> {
|
||||||
|
problem: &'a Problem,
|
||||||
|
blocks: Vec<(Position, Direction)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Problem {
|
||||||
|
pub fn new(size: Position) -> Self {
|
||||||
|
Self {
|
||||||
|
size,
|
||||||
|
blocks: Vec::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_block(&mut self, size: Position) -> BlockHandle {
|
||||||
|
self.blocks.push(Block {
|
||||||
|
size,
|
||||||
|
input: Vec::new(),
|
||||||
|
output: Vec::new(),
|
||||||
|
});
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
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),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Layout<'_> {
|
||||||
|
/// Create a new valid layout
|
||||||
|
pub fn new<'a, R: Rng + ?Sized>(problem: &'a Problem, rng: &'_ mut R) -> Layout<'a> {
|
||||||
|
let mut blocks = Vec::new();
|
||||||
|
|
||||||
|
assert!(Self::place_block(problem, &mut blocks, rng));
|
||||||
|
|
||||||
|
Layout { problem, blocks }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn place_block<R: Rng + ?Sized>(
|
||||||
|
problem: &'_ Problem,
|
||||||
|
blocks: &mut Vec<(Position, Direction)>,
|
||||||
|
rng: &'_ mut R,
|
||||||
|
) -> bool {
|
||||||
|
if problem.blocks.len() == blocks.len() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
let b = &problem.blocks[blocks.len()];
|
||||||
|
for _ in 0..1000 {
|
||||||
|
let dir = rng.gen::<Direction>();
|
||||||
|
|
||||||
|
let pos = match dir {
|
||||||
|
Direction::Up => Position::new(
|
||||||
|
rng.gen_range(0..=(problem.size.x - b.size.x)),
|
||||||
|
rng.gen_range(0..=(problem.size.y - b.size.y)),
|
||||||
|
),
|
||||||
|
Direction::Right => Position::new(
|
||||||
|
rng.gen_range((b.size.y - 1)..problem.size.x),
|
||||||
|
rng.gen_range(0..=(problem.size.y - b.size.x)),
|
||||||
|
),
|
||||||
|
Direction::Down => Position::new(
|
||||||
|
rng.gen_range((b.size.x - 1)..problem.size.x),
|
||||||
|
rng.gen_range((b.size.y - 1)..problem.size.y),
|
||||||
|
),
|
||||||
|
Direction::Left => Position::new(
|
||||||
|
rng.gen_range(0..=(problem.size.x - b.size.y)),
|
||||||
|
rng.gen_range((b.size.x - 1)..problem.size.y),
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
|
if blocks
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.all(|(i, (p, d))| !Self::collision((&problem.blocks[i], *p, *d), (b, pos, dir)))
|
||||||
|
{
|
||||||
|
blocks.push((pos, dir));
|
||||||
|
|
||||||
|
if Self::place_block(problem, blocks, rng) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
blocks.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Mutate existing layout, creating a valid layout
|
||||||
|
pub fn mutate<R: Rng + ?Sized>(&self, rng: &mut R) -> Self {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn collision(
|
||||||
|
block1: (&Block, Position, Direction),
|
||||||
|
block2: (&Block, Position, Direction),
|
||||||
|
) -> bool {
|
||||||
|
let (npos1, nsize1) = Self::normalize_pos(block1);
|
||||||
|
let (npos2, nsize2) = Self::normalize_pos(block2);
|
||||||
|
|
||||||
|
npos1.x < npos2.x + nsize2.x
|
||||||
|
&& npos1.x + nsize1.x > npos2.x
|
||||||
|
&& npos1.y < npos2.y + nsize2.y
|
||||||
|
&& npos1.y + nsize1.y > npos2.y
|
||||||
|
}
|
||||||
|
|
||||||
|
fn normalize_pos(block: (&Block, Position, Direction)) -> (Position, Position) {
|
||||||
|
let npos = match block.2 {
|
||||||
|
Direction::Up => block.1,
|
||||||
|
Direction::Right => block.1.in_direction(&Direction::Left, block.0.size.y - 1),
|
||||||
|
Direction::Down => block.1 - (block.0.size - Position::new(1, 1)),
|
||||||
|
Direction::Left => block.1.in_direction(&Direction::Up, block.0.size.x - 1),
|
||||||
|
};
|
||||||
|
let nsize = match block.2 {
|
||||||
|
Direction::Up | Direction::Down => block.0.size,
|
||||||
|
Direction::Right | Direction::Left => Position {
|
||||||
|
x: block.0.size.y,
|
||||||
|
y: block.0.size.x,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
(npos, nsize)
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sum
|
||||||
|
}
|
||||||
|
|
||||||
|
fn transform(pos: Position, dir: Direction, offset: Position) -> Position {
|
||||||
|
match dir {
|
||||||
|
Direction::Up => pos + offset,
|
||||||
|
Direction::Right => pos + Position::new(-offset.y, offset.x),
|
||||||
|
Direction::Down => pos - offset,
|
||||||
|
Direction::Left => pos + Position::new(offset.y, -offset.x),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn print(&self) {
|
||||||
|
let mut m: Map<Option<usize>> =
|
||||||
|
Map::new(self.problem.size.x as usize, self.problem.size.y as usize);
|
||||||
|
|
||||||
|
for (i, ((p, d), b)) in self
|
||||||
|
.blocks
|
||||||
|
.iter()
|
||||||
|
.zip(self.problem.blocks.iter())
|
||||||
|
.enumerate()
|
||||||
|
{
|
||||||
|
let (npos, nsize) = Self::normalize_pos((b, *p, *d));
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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, "#")
|
||||||
|
} else {
|
||||||
|
(ColorSpec::new(), " ")
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
pub mod belt_finding;
|
pub mod belt_finding;
|
||||||
pub mod blueprint;
|
pub mod blueprint;
|
||||||
pub mod graph;
|
pub mod graph;
|
||||||
|
pub mod layout;
|
||||||
pub mod misc;
|
pub mod misc;
|
||||||
pub mod priority_queue;
|
pub mod priority_queue;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue