factorio_blueprint/factorio-core/src/pathfield.rs

148 lines
3.6 KiB
Rust

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<F>(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(())
}