summaryrefslogtreecommitdiff
path: root/src/display.rs
diff options
context:
space:
mode:
authorElias Fleckenstein <eliasfleckenstein@web.de>2022-09-12 01:04:48 +0200
committerElias Fleckenstein <eliasfleckenstein@web.de>2022-09-12 01:04:48 +0200
commit1a1df3f1613a5c8814c6eb6d3d91744cca63cf3b (patch)
tree584b02079796dcef7152fcdcb650804ce0feea62 /src/display.rs
downloadrs2048-1a1df3f1613a5c8814c6eb6d3d91744cca63cf3b.tar.xz
Initial commit
Diffstat (limited to 'src/display.rs')
-rw-r--r--src/display.rs148
1 files changed, 148 insertions, 0 deletions
diff --git a/src/display.rs b/src/display.rs
new file mode 100644
index 0000000..6d750de
--- /dev/null
+++ b/src/display.rs
@@ -0,0 +1,148 @@
+use super::game::{Board, Pos};
+use ansi_term::Color;
+use std::fmt;
+
+enum Mode {
+ Roof_,
+ Data_,
+ Floor,
+ Empty,
+ Base_,
+}
+
+const FIELD_HEIGHT: usize = 3;
+const FIELD_WIDTH: usize = 8;
+
+fn write_line(f: &mut fmt::Formatter, vec: &[u32], mode: Mode) -> fmt::Result {
+ let mut vec = vec;
+ let len = vec.len();
+
+ write!(
+ f,
+ "{}",
+ match mode {
+ Mode::Roof_ => "┏",
+ Mode::Data_ => "┃",
+ Mode::Floor => "┠",
+ Mode::Empty => "┃",
+ Mode::Base_ => "┗",
+ }
+ )?;
+
+ for i in 0..len {
+ let &n = vec.last().unwrap();
+ vec = &vec[0..vec.len() - 1];
+
+ match mode {
+ Mode::Data_ | Mode::Empty => write!(f, "\x1b[0m ")?,
+ _ => {}
+ }
+
+ let color = match mode {
+ Mode::Data_ | Mode::Empty if n != 0 => {
+ let (r, g, b) = hsl::HSL {
+ h: (n * 360 / 12) as f64,
+ s: 1.0,
+ l: 0.5,
+ }
+ .to_rgb();
+
+ Color::Black.on(Color::RGB(r, g, b))
+ }
+ _ => Color::White.on(Color::Black),
+ };
+
+ if let Mode::Data_ = mode {
+ if n == 0 {
+ write!(f, "{}", " ".repeat(FIELD_WIDTH - 2))?;
+ } else {
+ write!(
+ f,
+ "{}",
+ color.paint(format!("{:^w$}", 1 << n, w = FIELD_WIDTH - 2))
+ )?;
+ }
+ } else {
+ write!(
+ f,
+ "{}",
+ match mode {
+ Mode::Roof_ | Mode::Base_ => "━".repeat(FIELD_WIDTH),
+ Mode::Floor => "─".repeat(FIELD_WIDTH),
+ Mode::Empty => color.paint(" ".repeat(FIELD_WIDTH - 2)).to_string(),
+ Mode::Data_ => panic!("unreachable"),
+ }
+ )?;
+ }
+
+ match mode {
+ Mode::Data_ | Mode::Empty => write!(f, " ")?,
+ _ => {}
+ }
+
+ if i != len - 1 {
+ write!(
+ f,
+ "{}",
+ match mode {
+ Mode::Roof_ => "┯",
+ Mode::Data_ => "│",
+ Mode::Floor => "┼",
+ Mode::Empty => "│",
+ Mode::Base_ => "┷",
+ }
+ )?;
+ }
+ }
+
+ write!(
+ f,
+ "{}",
+ match mode {
+ Mode::Roof_ => "┓",
+ Mode::Data_ => "┃",
+ Mode::Floor => "┨",
+ Mode::Empty => "┃",
+ Mode::Base_ => "┛",
+ }
+ )?;
+
+ writeln!(f)?;
+
+ Ok(())
+}
+
+impl fmt::Display for Board {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ let dummy = vec![0; self.size.x as usize];
+
+ write_line(f, &dummy, Mode::Roof_)?;
+
+ for y in 0..self.size.y {
+ let vec = (0..self.size.x)
+ .rev()
+ .map(|x| self.get(Pos::new(x, y)).value())
+ .collect::<Vec<u32>>();
+
+ for i in 0..FIELD_HEIGHT {
+ write_line(
+ f,
+ &vec,
+ if i == FIELD_HEIGHT / 2 {
+ Mode::Data_
+ } else {
+ Mode::Empty
+ },
+ )?;
+ }
+
+ if y != self.size.y - 1 {
+ write_line(f, &dummy, Mode::Floor)?;
+ }
+ }
+
+ write_line(f, &dummy, Mode::Base_)?;
+
+ Ok(())
+ }
+}