summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock10
-rw-r--r--Cargo.toml1
-rw-r--r--src/main.rs44
3 files changed, 43 insertions, 12 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 0eafa82..0d52afd 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -26,6 +26,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
[[package]]
+name = "nonblock"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "51c7a4f22e5f2e2bd805d6ab56f1ae87eb1815673e1b452048896fb687a8a3d4"
+dependencies = [
+ "libc",
+]
+
+[[package]]
name = "ppv-lite86"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -35,6 +44,7 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
name = "puzzle"
version = "0.1.0"
dependencies = [
+ "nonblock",
"rand",
"termios",
]
diff --git a/Cargo.toml b/Cargo.toml
index 3be4420..624495f 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -8,3 +8,4 @@ edition = "2021"
[dependencies]
rand = "0.8.5"
termios = "0.3.3"
+nonblock = "0.2.0"
diff --git a/src/main.rs b/src/main.rs
index 245c2b1..fc8c0a5 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,7 +1,8 @@
extern crate termios;
use rand::Rng;
-use std::io::Read;
+use std::time::Duration;
+use nonblock::NonBlockingReader;
const FIELD_COLS: usize = 10;
const FIELD_ROWS_VISIBLE: usize = 20;
@@ -18,6 +19,12 @@ const CELLS_S: [i8; FIGURE_SIZE] = [0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0,
const CELLS_T: [i8; FIGURE_SIZE] = [0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0];
const CELLS_Z: [i8; FIGURE_SIZE] = [0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0];
+enum StepResult {
+ StateChanged,
+ Quit,
+ Noop,
+}
+
#[derive(Clone)]
#[derive(Debug)]
enum FigureKind {
@@ -165,11 +172,13 @@ impl Game {
self.x = 0;
self.y = 0;
}
- fn step(&mut self, fd: &mut std::io::Stdin) -> Option<()> {
- let mut r: [u8;1]=[0];
- fd.read(&mut r[..]).unwrap();
- match r[0] as char {
- 'q' => return None,
+ fn step(&mut self, c_optional: Option<char>) -> StepResult {
+ if let None = c_optional {
+ return StepResult::Noop;
+ }
+ let c = c_optional.unwrap();
+ match c {
+ 'q' => return StepResult::Quit,
' ' => {
if !self.field.has_collision(&self.figure, self.x, self.y) {
self.place()
@@ -212,7 +221,7 @@ impl Game {
}
_ => {},
}
- Some(())
+ StepResult::StateChanged
}
}
@@ -266,12 +275,23 @@ fn main() {
clear_screen();
let mut game = Game::default();
display_game(&game);
- let mut stdin = std::io::stdin();
- loop {
- if let None = game.step(&mut stdin) {
- break;
+ let mut noblock_stdin = NonBlockingReader::from_fd(std::io::stdin()).unwrap();
+ 'outer: while !noblock_stdin.is_eof() {
+ let mut buf = String::new();
+ noblock_stdin.read_available_to_string(&mut buf).unwrap();
+ let mut changed = false;
+ for c in buf.bytes() {
+ let result = game.step(Some(c as char));
+ match result {
+ StepResult::StateChanged => changed = true,
+ StepResult::Noop => {},
+ StepResult::Quit => break 'outer,
+ }
+ }
+ if changed {
+ display_game(&game);
}
- display_game(&game);
+ std::thread::sleep(Duration::from_millis(1));
}
termios::tcsetattr(0, termios::TCSADRAIN, &termios_state_initial).unwrap();
}