summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main.rs78
1 files changed, 56 insertions, 22 deletions
diff --git a/src/main.rs b/src/main.rs
index 2cf1b23..468da4c 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,6 +1,6 @@
extern crate termios;
-use rand::Rng;
+use rand::seq::SliceRandom;
use nonblock::NonBlockingReader;
const FIELD_COLS: usize = 10;
@@ -29,9 +29,9 @@ enum FigureKind {
I,
L2,
L,
- T,
B,
S,
+ T,
Z,
}
@@ -69,25 +69,17 @@ struct Figure {
}
impl Figure {
- fn kind_random() -> Self {
- return match rand::thread_rng().gen_range(0..7) {
- 0 => Self::kind_i(),
- 1 => Self::kind_l2(),
- 2 => Self::kind_l(),
- 3 => Self::kind_b(),
- 4 => Self::kind_s(),
- 5 => Self::kind_t(),
- 6 => Self::kind_z(),
- _ => unreachable!(),
- };
+ fn from_kind(kind: FigureKind) -> Self {
+ match kind {
+ FigureKind::I => Self{ cells: CELLS_I, kind },
+ FigureKind::L2 => Self{ cells: CELLS_L2, kind },
+ FigureKind::L => Self{ cells: CELLS_L, kind },
+ FigureKind::B => Self{ cells: CELLS_B, kind },
+ FigureKind::S => Self{ cells: CELLS_S, kind },
+ FigureKind::T => Self{ cells: CELLS_T, kind },
+ FigureKind::Z => Self{ cells: CELLS_Z, kind },
+ }
}
- const fn kind_i() -> Self { Self{ cells: CELLS_I, kind: FigureKind::I } }
- const fn kind_l2() -> Self { Self{ cells: CELLS_L2, kind: FigureKind::L2 } }
- const fn kind_l() -> Self { Self{ cells: CELLS_L, kind: FigureKind::L } }
- const fn kind_b() -> Self { Self{ cells: CELLS_B, kind: FigureKind::B } }
- const fn kind_s() -> Self { Self{ cells: CELLS_S, kind: FigureKind::S } }
- const fn kind_t() -> Self { Self{ cells: CELLS_T, kind: FigureKind::T } }
- const fn kind_z() -> Self { Self{ cells: CELLS_Z, kind: FigureKind::Z } }
fn rotate_cw_4x4(&mut self) {
let mut tmp: [u8; 4 * 4] = Default::default();
for y in 0..4 {
@@ -190,6 +182,44 @@ impl Field {
}
}
+struct Bag {
+ index: u8,
+ pieces: [u8; 7],
+}
+
+impl Bag {
+ fn next(&mut self) -> FigureKind {
+ if self.index >= 7 {
+ self.index = 0;
+ self.pieces.shuffle(&mut rand::thread_rng());
+ }
+ let i = self.index;
+ self.index += 1;
+ match self.pieces[i as usize] {
+ 0 => FigureKind::I,
+ 1 => FigureKind::L2,
+ 2 => FigureKind::L,
+ 4 => FigureKind::B,
+ 5 => FigureKind::S,
+ 3 => FigureKind::T,
+ 6 => FigureKind::Z,
+ _ => unreachable!(),
+ }
+ }
+}
+
+impl Default for Bag {
+ #[inline]
+ fn default() -> Self {
+ let mut pieces: [u8; 7] = [0, 1, 2, 3, 4, 5, 6];
+ pieces.shuffle(&mut rand::thread_rng());
+ Self{
+ index: 0,
+ pieces
+ }
+ }
+}
+
struct Game {
field: Field,
figure: Figure,
@@ -197,18 +227,22 @@ struct Game {
y: isize,
fall_timeout: Timeout,
place_timeout: Option<Timeout>,
+ bag: Bag,
}
impl Default for Game {
#[inline]
fn default() -> Self {
+ let mut bag = Bag::default();
+ let kind = bag.next();
Self{
field: Field::default(),
- figure: Figure::kind_random(),
+ figure: Figure::from_kind(kind),
x: 3,
y: 17,
fall_timeout: Timeout::from_duration(std::time::Duration::from_millis(500)),
place_timeout: None,
+ bag,
}
}
}
@@ -216,7 +250,7 @@ impl Default for Game {
impl Game {
fn place_figure(&mut self) {
self.field.render(&self.figure, self.x, self.y);
- self.figure = Figure::kind_random();
+ self.figure = Figure::from_kind(self.bag.next());
(self.x, self.y) = (3, 17);
self.stop_place_timeout();
for line in 0..FIELD_ROWS - 1 {