Refactor visualize.

This commit is contained in:
hal8174 2024-08-26 16:58:14 +02:00
parent 5a6be3194e
commit 0c1345053b
3 changed files with 189 additions and 181 deletions

View file

@ -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<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));
}
}

108
src/common/visualize/mod.rs Normal file
View file

@ -0,0 +1,108 @@
mod print;
use std::collections::HashMap;
use crate::prelude::*;
pub trait Visualize {
fn visualize(&self) -> Visualization;
fn print_visualization(&self) {
let v = self.visualize();
print::print(v);
}
}
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));
}
}

View file

@ -0,0 +1,81 @@
use super::Visualization;
use std::io::Write;
use termcolor::{ColorSpec, StandardStream, WriteColor};
use crate::prelude::*;
pub(super) fn print(v: Visualization) {
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();
}
}