diff --git a/examples/layout.rs b/examples/layout.rs index 9fd5c3c..d16e88e 100644 --- a/examples/layout.rs +++ b/examples/layout.rs @@ -1,8 +1,4 @@ -use factorio_blueprint::{ - belt_finding::{conflict_avoidance::ConflictAvoidance, Problem}, - common::visualize::Visualize, - layout::Layout, -}; +use factorio_blueprint::layout::Layout; use rand::SeedableRng; fn main() { @@ -19,29 +15,14 @@ fn main() { let p = serde_yaml::from_reader(file).unwrap(); + dbg!(&p); + for i in 0..1 { - let mut rng = rand::rngs::SmallRng::seed_from_u64(5); + let mut rng = rand::rngs::SmallRng::seed_from_u64(i); let l = Layout::new(&p, &mut rng); - // let s = l.score(); - 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); - // } + println!("Seed: {i}, Score {}", l.score()); + l.print(); } } diff --git a/layout.yml b/layout.yml index 4189f8f..8b10714 100644 --- a/layout.yml +++ b/layout.yml @@ -1,6 +1,6 @@ size: - x: 15 - y: 15 + x: 10 + y: 10 blocks: - size: x: 3 @@ -9,7 +9,7 @@ blocks: - offset: x: 1 y: 1 - dir: Up + dir: Down output: - offset: x: 1 @@ -31,14 +31,10 @@ blocks: - offset: x: 0 y: 1 - dir: Right + dir: Left output: connections: - startblock: 1 startpoint: 0 endblock: 0 endpoint: 0 - - startblock: 0 - startpoint: 0 - endblock: 2 - endpoint: 0 diff --git a/src/belt_finding/mod.rs b/src/belt_finding/mod.rs index 0648f41..e8e6269 100644 --- a/src/belt_finding/mod.rs +++ b/src/belt_finding/mod.rs @@ -1,6 +1,5 @@ use crate::common::color::COLORS; use crate::graph::wheighted_graph::WheightedGraph; -use crate::layout::Layout; use crate::misc::Map; use crate::{ graph::wheighted_graph::shortest_path::dijkstra, priority_queue::fibonacci_heap::FibonacciHeap, @@ -37,49 +36,6 @@ 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)) { self.start.push(start); self.end.push(end); diff --git a/src/common/mod.rs b/src/common/mod.rs index a4a8298..30537fe 100644 --- a/src/common/mod.rs +++ b/src/common/mod.rs @@ -1,4 +1,3 @@ pub mod color; pub mod direction; pub mod position; -pub mod visualize; diff --git a/src/common/visualize.rs b/src/common/visualize.rs deleted file mode 100644 index 2ff7ba1..0000000 --- a/src/common/visualize.rs +++ /dev/null @@ -1,181 +0,0 @@ -use std::collections::HashMap; - -use std::io::Write; -use termcolor::{ColorSpec, StandardStream, WriteColor}; - -use crate::prelude::*; - -pub trait Visualize { - fn visualize(&self) -> Visualization; - - fn print_visualization(&self) { - let v = self.visualize(); - - let stdout = &mut StandardStream::stdout(termcolor::ColorChoice::Always); - - let width_digits = (v.size.x - 1).ilog10() + 1; - let height_digits = (v.size.y - 1).ilog10() + 1; - - // print header - for i in 0..width_digits { - let d = width_digits - i - 1; - - //padding - for _ in 0..height_digits { - write!(stdout, " ").unwrap(); - } - - for x in 0..v.size.x { - let digits = x / (i32::pow(10, d)); - if digits == 0 && d > 0 { - write!(stdout, " ").unwrap(); - } else { - write!( - stdout, - "{}", - char::from_u32((digits % 10) as u32 + 48).unwrap() - ) - .unwrap(); - } - } - writeln!(stdout).unwrap(); - } - - for y in 0..v.size.y { - write!(stdout, "{:1$}", y, height_digits as usize).unwrap(); - - for x in 0..v.size.x { - if let Some((s, fg, bg)) = v.symbols.get(&Position::new(x, y)) { - let mut c = ColorSpec::new(); - c.set_fg(fg.as_ref().map(|c| termcolor::Color::Rgb(c.r, c.g, c.b))); - c.set_bg(bg.as_ref().map(|c| termcolor::Color::Rgb(c.r, c.g, c.b))); - stdout.set_color(&c).unwrap(); - write!(stdout, "{:1}", s.get_str()).unwrap(); - stdout.reset().unwrap(); - } else { - write!(stdout, " ").unwrap(); - } - } - - writeln!(stdout, "{:1$}", y, height_digits as usize).unwrap(); - } - - for i in 0..width_digits { - let d = width_digits - i - 1; - - //padding - for _ in 0..height_digits { - write!(stdout, " ").unwrap(); - } - - for x in 0..v.size.x { - let digits = x / (i32::pow(10, d)); - if digits == 0 && d > 0 { - write!(stdout, " ").unwrap(); - } else { - write!( - stdout, - "{}", - char::from_u32((digits % 10) as u32 + 48).unwrap() - ) - .unwrap(); - } - } - writeln!(stdout).unwrap(); - } - } -} - -pub enum Symbol { - Arrow(Direction), - ArrowEnter(Direction), - ArrowExit(Direction), - Char(&'static str), - Block, - Space, -} - -impl Symbol { - fn get_str(&self) -> &'static str { - match self { - Symbol::Arrow(dir) => match dir { - Direction::Up => "↑", - Direction::Right => "→", - Direction::Down => "↓", - Direction::Left => "←", - }, - Symbol::ArrowEnter(dir) => match dir { - Direction::Up => "↟", - Direction::Right => "↠", - Direction::Down => "↡", - Direction::Left => "↞", - }, - Symbol::ArrowExit(dir) => match dir { - Direction::Up => "↥", - Direction::Right => "↦", - Direction::Down => "↧", - Direction::Left => "↤", - }, - Symbol::Char(c) => c.split_at(1).0, - Symbol::Block => "#", - Symbol::Space => " ", - } - } - - fn get_char(&self) -> char { - self.get_str().chars().next().unwrap() - } -} - -pub struct Visualization { - size: Position, - symbols: HashMap, Option)>, -} - -#[derive(Debug, Clone, Copy)] -pub struct Color { - r: u8, - g: u8, - b: u8, -} - -impl Color { - pub fn new(r: u8, g: u8, b: u8) -> Self { - Self { r, g, b } - } - - pub fn index(i: usize) -> Self { - let c = [ - Color::new(0xe6, 0x00, 0x49), - Color::new(0x0b, 0xb4, 0xff), - Color::new(0x50, 0xe9, 0x91), - Color::new(0xe6, 0xd8, 0x00), - Color::new(0x9b, 0x19, 0xf5), - Color::new(0xff, 0xa3, 0x00), - Color::new(0xdc, 0x0a, 0xb4), - Color::new(0xb3, 0xd4, 0xff), - Color::new(0x00, 0xbf, 0xa0), - ]; - - c[i % c.len()] - } -} - -impl Visualization { - pub fn new(size: Position) -> Self { - Self { - size, - symbols: HashMap::new(), - } - } - - pub fn add_symbol( - &mut self, - pos: Position, - symbol: Symbol, - fg: Option, - bg: Option, - ) { - self.symbols.insert(pos, (symbol, fg, bg)); - } -} diff --git a/src/layout/mod.rs b/src/layout/mod.rs index 5bb391f..b3f1ae4 100644 --- a/src/layout/mod.rs +++ b/src/layout/mod.rs @@ -1,43 +1,45 @@ -use crate::common::visualize::{Color, Symbol, Visualization, Visualize}; use crate::prelude::*; +use crate::{belt_finding::common::print_map, misc::Map}; + use rand::Rng; use serde::{Deserialize, Serialize}; +use termcolor::ColorSpec; #[derive(Debug, Serialize, Deserialize)] -pub(crate) struct Block { - pub(crate) size: Position, - pub(crate) input: Vec, - pub(crate) output: Vec, +struct Block { + size: Position, + input: Vec, + output: Vec, } #[derive(Debug, Serialize, Deserialize)] -pub(crate) struct Interface { - pub(crate) offset: Position, - pub(crate) dir: Direction, +struct Interface { + offset: Position, + dir: Direction, } #[derive(Debug, Serialize, Deserialize)] -pub(crate) struct Connection { - pub(crate) startblock: usize, - pub(crate) startpoint: usize, - pub(crate) endblock: usize, - pub(crate) endpoint: usize, +struct Connection { + startblock: usize, + startpoint: usize, + endblock: usize, + endpoint: usize, } #[derive(Debug, Serialize, Deserialize)] pub struct Problem { - pub(crate) size: Position, - pub(crate) blocks: Vec, - pub(crate) connections: Vec, + size: Position, + blocks: Vec, + connections: Vec, } #[derive(Debug, Clone, Copy)] pub struct BlockHandle(usize); -#[derive(Debug, Clone)] +#[derive(Debug)] pub struct Layout<'a> { - pub(crate) problem: &'a Problem, - pub(crate) blocks: Vec<(Position, Direction)>, + problem: &'a Problem, + blocks: Vec<(Position, Direction)>, } impl Problem { @@ -143,9 +145,7 @@ impl Layout<'_> { /// Mutate existing layout, creating a valid layout pub fn mutate(&self, rng: &mut R) -> Self { - let s = self.clone(); - - s + todo!() } fn collision( @@ -161,7 +161,7 @@ impl Layout<'_> { && npos1.y + nsize1.y > npos2.y } - pub(crate) fn normalize_pos(block: (&Block, Position, Direction)) -> (Position, Position) { + 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), @@ -200,7 +200,7 @@ impl Layout<'_> { sum } - pub(crate) fn transform(pos: Position, dir: Direction, offset: Position) -> Position { + fn transform(pos: Position, dir: Direction, offset: Position) -> Position { match dir { Direction::Up => pos + offset, Direction::Right => pos + Position::new(-offset.y, offset.x), @@ -209,28 +209,9 @@ impl Layout<'_> { } } - 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> { - fn visualize(&self) -> Visualization { - let mut v = Visualization::new(self.problem.size); + pub fn print(&self) { + let mut m: Map> = + Map::new(self.problem.size.x as usize, self.problem.size.y as usize); for (i, ((p, d), b)) in self .blocks @@ -238,33 +219,39 @@ impl<'a> Visualize for Layout<'a> { .zip(self.problem.blocks.iter()) .enumerate() { - let c = Color::index(i); - 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) { - v.add_symbol(Position::new(x, y), Symbol::Block, Some(c), None); + m.set(x as usize, y as usize, Some((i, "#"))); } } let pos = Self::transform(*p, *d, Position::new(0, 0)); - v.add_symbol(pos, Symbol::Char("X"), Some(c), None); + 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); - v.add_symbol(pos, Symbol::Char("i"), Some(c), None); + 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); - v.add_symbol(pos, Symbol::Char("o"), Some(c), None); + m.set(pos.x as usize, pos.y as usize, Some((i, "o"))); } } - v + 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(crate::common::color::COLORS[i.0])); + (color, i.1) + } else { + (ColorSpec::new(), " ") + } + }); } }