use std::io::{self, Write}; use termcolor::{ColorSpec, StandardStream, WriteColor}; use crate::prelude::*; #[derive(Clone, Debug, Copy)] pub enum PathField { Belt { pos: Position, dir: Direction, }, Underground { pos: Position, dir: Direction, len: u8, }, } impl PathField { pub fn pos(&self) -> &Position { match self { PathField::Belt { pos, dir: _ } => pos, PathField::Underground { pos, dir: _, len: _, } => pos, } } pub fn dir(&self) -> &Direction { match self { PathField::Belt { pos: _, dir } => dir, PathField::Underground { pos: _, dir, len: _, } => dir, } } pub fn end_pos(&self) -> (Position, Direction) { match self { PathField::Belt { pos, dir } => (*pos, *dir), PathField::Underground { pos, dir, len } => { (pos.in_direction(dir, *len as PositionType), *dir) } } } pub fn offset(&self, offset: &Position) -> Self { match self { PathField::Belt { pos, dir } => PathField::Belt { pos: Position::new(pos.x + offset.x, pos.y + offset.y), dir: *dir, }, PathField::Underground { pos, dir, len } => PathField::Underground { pos: Position::new(pos.x + offset.x, pos.y + offset.y), dir: *dir, len: *len, }, } } pub fn cost(&self) -> usize { match self { PathField::Belt { pos: _, dir: _ } => 150, PathField::Underground { pos: _, dir: _, len: _, } => 1750, } } } pub fn print_map(width: i32, height: i32, f: F) -> io::Result<()> where F: Fn(i32, i32) -> (ColorSpec, &'static str), { let stdout = &mut StandardStream::stdout(termcolor::ColorChoice::Always); let width_digits = (width - 1).ilog10() + 1; let height_digits = (height - 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, " ")?; } for x in 0..width { let digits = x / (i32::pow(10, d)); if digits == 0 && d > 0 { write!(stdout, " ")?; } else { write!( stdout, "{}", char::from_u32((digits % 10) as u32 + 48).unwrap() )?; } } writeln!(stdout)?; } for y in 0..height { write!(stdout, "{:1$}", y, height_digits as usize)?; for x in 0..width { let (c, s) = f(x, y); stdout.set_color(&c)?; write!(stdout, "{:1}", s)?; stdout.reset()?; } writeln!(stdout, "{:1$}", y, height_digits as usize)?; } for i in 0..width_digits { let d = width_digits - i - 1; //padding for _ in 0..height_digits { write!(stdout, " ")?; } for x in 0..width { let digits = x / (i32::pow(10, d)); if digits == 0 && d > 0 { write!(stdout, " ")?; } else { write!( stdout, "{}", char::from_u32((digits % 10) as u32 + 48).unwrap() )?; } } writeln!(stdout)?; } Ok(()) }