summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/display.rs126
-rw-r--r--src/main.rs63
2 files changed, 105 insertions, 84 deletions
diff --git a/src/display.rs b/src/display.rs
index 6d750de..fba426a 100644
--- a/src/display.rs
+++ b/src/display.rs
@@ -1,6 +1,5 @@
use super::game::{Board, Pos};
-use ansi_term::Color;
-use std::fmt;
+use crossterm::{cursor, queue, style::*};
enum Mode {
Roof_,
@@ -13,20 +12,19 @@ enum Mode {
const FIELD_HEIGHT: usize = 3;
const FIELD_WIDTH: usize = 8;
-fn write_line(f: &mut fmt::Formatter, vec: &[u32], mode: Mode) -> fmt::Result {
+fn write_line(stdout: &mut std::io::Stdout, vec: &[u32], mode: Mode) -> crossterm::Result<()> {
let mut vec = vec;
let len = vec.len();
- write!(
- f,
- "{}",
- match mode {
+ queue!(
+ stdout,
+ Print(match mode {
Mode::Roof_ => "┏",
Mode::Data_ => "┃",
Mode::Floor => "┠",
Mode::Empty => "┃",
Mode::Base_ => "┗",
- }
+ })
)?;
for i in 0..len {
@@ -34,11 +32,11 @@ fn write_line(f: &mut fmt::Formatter, vec: &[u32], mode: Mode) -> fmt::Result {
vec = &vec[0..vec.len() - 1];
match mode {
- Mode::Data_ | Mode::Empty => write!(f, "\x1b[0m ")?,
+ Mode::Data_ | Mode::Empty => queue!(stdout, Print(" "))?,
_ => {}
}
- let color = match mode {
+ match mode {
Mode::Data_ | Mode::Empty if n != 0 => {
let (r, g, b) = hsl::HSL {
h: (n * 360 / 12) as f64,
@@ -47,102 +45,100 @@ fn write_line(f: &mut fmt::Formatter, vec: &[u32], mode: Mode) -> fmt::Result {
}
.to_rgb();
- Color::Black.on(Color::RGB(r, g, b))
+ queue!(
+ stdout,
+ SetColors(Colors::new(Color::Black, Color::Rgb { r, g, b }))
+ )?;
}
- _ => Color::White.on(Color::Black),
+ _ => {}
};
if let Mode::Data_ = mode {
if n == 0 {
- write!(f, "{}", " ".repeat(FIELD_WIDTH - 2))?;
+ queue!(stdout, Print(" ".repeat(FIELD_WIDTH - 2)))?;
} else {
- write!(
- f,
- "{}",
- color.paint(format!("{:^w$}", 1 << n, w = FIELD_WIDTH - 2))
+ queue!(
+ stdout,
+ Print(format!("{:^w$}", 1 << n, w = FIELD_WIDTH - 2))
)?;
}
} else {
- write!(
- f,
- "{}",
- match mode {
+ queue!(
+ stdout,
+ Print(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::Empty => " ".repeat(FIELD_WIDTH - 2),
Mode::Data_ => panic!("unreachable"),
- }
+ })
)?;
}
match mode {
- Mode::Data_ | Mode::Empty => write!(f, " ")?,
+ Mode::Data_ | Mode::Empty => {
+ queue!(stdout, Print(" "), SetAttribute(Attribute::Reset))?
+ }
_ => {}
}
if i != len - 1 {
- write!(
- f,
- "{}",
- match mode {
+ queue!(
+ stdout,
+ Print(match mode {
Mode::Roof_ => "┯",
Mode::Data_ => "│",
Mode::Floor => "┼",
Mode::Empty => "│",
Mode::Base_ => "┷",
- }
+ })
)?;
}
}
- write!(
- f,
- "{}",
- match mode {
+ queue!(
+ stdout,
+ Print(match mode {
Mode::Roof_ => "┓",
Mode::Data_ => "┃",
Mode::Floor => "┨",
Mode::Empty => "┃",
Mode::Base_ => "┛",
- }
+ }),
+ cursor::MoveToNextLine(1),
)?;
- 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
- },
- )?;
- }
+pub fn display_board(stdout: &mut std::io::Stdout, board: &Board) -> crossterm::Result<()> {
+ let dummy = vec![0; board.size.x as usize];
+
+ write_line(stdout, &dummy, Mode::Roof_)?;
+
+ for y in 0..board.size.y {
+ let vec = (0..board.size.x)
+ .rev()
+ .map(|x| board.get(Pos::new(x, y)).value())
+ .collect::<Vec<u32>>();
+
+ for i in 0..FIELD_HEIGHT {
+ write_line(
+ stdout,
+ &vec,
+ if i == FIELD_HEIGHT / 2 {
+ Mode::Data_
+ } else {
+ Mode::Empty
+ },
+ )?;
+ }
- if y != self.size.y - 1 {
- write_line(f, &dummy, Mode::Floor)?;
- }
+ if y != board.size.y - 1 {
+ write_line(stdout, &dummy, Mode::Floor)?;
}
+ }
- write_line(f, &dummy, Mode::Base_)?;
+ write_line(stdout, &dummy, Mode::Base_)?;
- Ok(())
- }
+ Ok(())
}
diff --git a/src/main.rs b/src/main.rs
index a7b3e59..e04f92c 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,31 +1,56 @@
pub mod display;
pub mod game;
+use crossterm::{cursor, event, execute, queue, terminal};
use game::{Board, Dir::*, Pos};
+use std::io::Write;
fn main() {
let mut rng = rand::thread_rng();
- let getch = getch::Getch::new();
- let board = Board::new(Pos::new(4, 4));
+ let mut stdout = std::io::stdout();
+ queue!(stdout, terminal::EnterAlternateScreen, cursor::Hide).unwrap();
+
+ terminal::enable_raw_mode().unwrap();
+
+ let board = Board::new(Pos::new(4, 4));
board.spawn(&mut rng);
- clearscreen::clear().unwrap();
- print!("{board}");
-
- while let Ok(ch) = getch.getch() {
- if !board.step(match ch {
- b'w' => Up,
- b'a' => Left,
- b's' => Down,
- b'd' => Right,
- b'q' => break,
- _ => continue,
- }) {
- continue;
- }
+ board.spawn(&mut rng);
+
+ loop {
+ queue!(
+ stdout,
+ terminal::Clear(terminal::ClearType::All),
+ cursor::MoveTo(0, 0)
+ )
+ .unwrap();
+ display::display_board(&mut stdout, &board).unwrap();
+ stdout.flush().unwrap();
- board.spawn(&mut rng);
- clearscreen::clear().unwrap();
- print!("{board}");
+ if let Ok(evt) = event::read() {
+ match evt {
+ event::Event::Key(event::KeyEvent { code, .. }) => match code {
+ event::KeyCode::Char(ch) => {
+ if board.step(match ch.to_ascii_lowercase() {
+ 'w' => Up,
+ 'a' => Left,
+ 's' => Down,
+ 'd' => Right,
+ 'q' => break,
+ _ => continue,
+ }) {
+ board.spawn(&mut rng);
+ }
+ }
+ _ => {}
+ },
+ _ => {}
+ }
+ } else {
+ break;
+ }
}
+
+ terminal::disable_raw_mode().unwrap();
+ execute!(stdout, cursor::Show, terminal::LeaveAlternateScreen).unwrap();
}