Compare commits
	
		
			2 commits
		
	
	
		
			48419b4674
			...
			5a6be3194e
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 5a6be3194e | |||
| c572fcb0e2 | 
					 6 changed files with 312 additions and 50 deletions
				
			
		|  | @ -1,4 +1,8 @@ | ||||||
| use factorio_blueprint::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,14 +19,29 @@ fn main() { | ||||||
| 
 | 
 | ||||||
|     let p = serde_yaml::from_reader(file).unwrap(); |     let p = serde_yaml::from_reader(file).unwrap(); | ||||||
| 
 | 
 | ||||||
|     dbg!(&p); |  | ||||||
| 
 |  | ||||||
|     for i in 0..1 { |     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(); |         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);
 | ||||||
|  |         // }
 | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										12
									
								
								layout.yml
									
										
									
									
									
								
							
							
						
						
									
										12
									
								
								layout.yml
									
										
									
									
									
								
							|  | @ -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 | ||||||
|  |  | ||||||
|  | @ -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); | ||||||
|  |  | ||||||
|  | @ -1,3 +1,4 @@ | ||||||
| pub mod color; | pub mod color; | ||||||
| pub mod direction; | pub mod direction; | ||||||
| pub mod position; | pub mod position; | ||||||
|  | pub mod visualize; | ||||||
|  |  | ||||||
							
								
								
									
										181
									
								
								src/common/visualize.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										181
									
								
								src/common/visualize.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,181 @@ | ||||||
|  | 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<Position, (Symbol, Option<Color>, Option<Color>)>, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[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<Color>, | ||||||
|  |         bg: Option<Color>, | ||||||
|  |     ) { | ||||||
|  |         self.symbols.insert(pos, (symbol, fg, bg)); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -1,45 +1,43 @@ | ||||||
|  | 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)] | ||||||
| pub struct BlockHandle(usize); | pub struct BlockHandle(usize); | ||||||
| 
 | 
 | ||||||
| #[derive(Debug)] | #[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 { | ||||||
|  | @ -145,7 +143,9 @@ impl Layout<'_> { | ||||||
| 
 | 
 | ||||||
|     /// Mutate existing layout, creating a valid layout
 |     /// Mutate existing layout, creating a valid layout
 | ||||||
|     pub fn mutate<R: Rng + ?Sized>(&self, rng: &mut R) -> Self { |     pub fn mutate<R: Rng + ?Sized>(&self, rng: &mut R) -> Self { | ||||||
|         todo!() |         let s = self.clone(); | ||||||
|  | 
 | ||||||
|  |         s | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fn collision( |     fn collision( | ||||||
|  | @ -161,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), | ||||||
|  | @ -200,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), | ||||||
|  | @ -209,9 +209,28 @@ impl Layout<'_> { | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub fn print(&self) { |     pub(crate) fn rotate(dir: Direction, rot: Direction) -> Direction { | ||||||
|         let mut m: Map<Option<(usize, &str)>> = |         match (rot, dir) { | ||||||
|             Map::new(self.problem.size.x as usize, self.problem.size.y as usize); |             (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); | ||||||
| 
 | 
 | ||||||
|         for (i, ((p, d), b)) in self |         for (i, ((p, d), b)) in self | ||||||
|             .blocks |             .blocks | ||||||
|  | @ -219,39 +238,33 @@ impl Layout<'_> { | ||||||
|             .zip(self.problem.blocks.iter()) |             .zip(self.problem.blocks.iter()) | ||||||
|             .enumerate() |             .enumerate() | ||||||
|         { |         { | ||||||
|  |             let c = Color::index(i); | ||||||
|  | 
 | ||||||
|             let (npos, nsize) = Self::normalize_pos((b, *p, *d)); |             let (npos, nsize) = Self::normalize_pos((b, *p, *d)); | ||||||
| 
 | 
 | ||||||
|             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, "#"))); |                     v.add_symbol(Position::new(x, y), Symbol::Block, Some(c), None); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             let pos = Self::transform(*p, *d, Position::new(0, 0)); |             let pos = Self::transform(*p, *d, Position::new(0, 0)); | ||||||
| 
 | 
 | ||||||
|             m.set(pos.x as usize, pos.y as usize, Some((i, "X"))); |             v.add_symbol(pos, Symbol::Char("X"), Some(c), None); | ||||||
| 
 | 
 | ||||||
|             for input in &b.input { |             for input in &b.input { | ||||||
|                 let pos = Self::transform(*p, *d, input.offset); |                 let pos = Self::transform(*p, *d, input.offset); | ||||||
| 
 | 
 | ||||||
|                 m.set(pos.x as usize, pos.y as usize, Some((i, "i"))); |                 v.add_symbol(pos, Symbol::Char("i"), Some(c), None); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             for output in &b.output { |             for output in &b.output { | ||||||
|                 let pos = Self::transform(*p, *d, output.offset); |                 let pos = Self::transform(*p, *d, output.offset); | ||||||
| 
 | 
 | ||||||
|                 m.set(pos.x as usize, pos.y as usize, Some((i, "o"))); |                 v.add_symbol(pos, Symbol::Char("o"), Some(c), None); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         let _ = print_map(self.problem.size.x, self.problem.size.y, |x, y| { |         v | ||||||
|             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(), " ") |  | ||||||
|             } |  | ||||||
|         }); |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue