summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorOxore <oxore@protonmail.com>2023-08-01 00:40:36 +0300
committerOxore <oxore@protonmail.com>2023-08-01 00:41:01 +0300
commit2d43dc5963e76e143b4d786051cccde0ab3cb1f8 (patch)
treecd5a316fcf451f0e8f6159c2b2a7360c47f777b1 /src
parent230f296eb2639ae6cdac60f5fda03d3926cd959e (diff)
Impl ghost figure, fix hold when about to place
Diffstat (limited to 'src')
-rw-r--r--src/main.rs64
1 files changed, 42 insertions, 22 deletions
diff --git a/src/main.rs b/src/main.rs
index 33a369c..807a813 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -20,6 +20,7 @@ const CELLS_Z: [u8; FIGURE_SIZE] = [0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0,
const NEXT_COUNT: usize = 4;
const DISPLAY_NEXT_OFFSET_DOWN: usize = 4;
const DISPLAY_HOLD_OFFSET_DOWN: usize = 4;
+const GHOST_MASK: u8 = 8;
enum StepResult {
StateChanged,
@@ -144,7 +145,8 @@ impl Field {
} else if f_y >= FIELD_ROWS as isize {
continue;
}
- if figure.cells[i] != 0 {
+ let color = figure.cells[i] & !GHOST_MASK;
+ if color != 0 {
self.cells[f_x as usize + f_y as usize * FIELD_COLS] = figure.cells[i];
}
}
@@ -153,7 +155,8 @@ impl Field {
for i in 0..FIGURE_SIZE {
let f_x = (i % FIGURE_SIZE_COLS) as isize + x;
let f_y = (i / FIGURE_SIZE_ROWS) as isize + y;
- if figure.cells[i] != 0 {
+ let color = figure.cells[i] & !GHOST_MASK;
+ if color != 0 {
if f_x < 0 {
return true;
} else if f_x >= FIELD_COLS as isize {
@@ -162,8 +165,11 @@ impl Field {
return true;
} else if f_y >= FIELD_ROWS as isize {
return true;
- } else if self.cells[f_x as usize + f_y as usize * FIELD_COLS] != 0 {
- return true;
+ } else {
+ let fcolor = self.cells[f_x as usize + f_y as usize * FIELD_COLS] & !GHOST_MASK;
+ if fcolor != 0 {
+ return true;
+ }
}
}
}
@@ -199,13 +205,13 @@ impl Bag {
let i = self.index;
self.index += 1;
match self.pieces[i as usize] {
- 0 => FigureKind::I,
- 1 => FigureKind::J,
- 2 => FigureKind::L,
- 4 => FigureKind::O,
- 5 => FigureKind::S,
- 3 => FigureKind::T,
- 6 => FigureKind::Z,
+ 1 => FigureKind::I,
+ 2 => FigureKind::J,
+ 3 => FigureKind::L,
+ 5 => FigureKind::O,
+ 6 => FigureKind::S,
+ 4 => FigureKind::T,
+ 7 => FigureKind::Z,
_ => unreachable!(),
}
}
@@ -214,7 +220,7 @@ impl Bag {
impl Default for Bag {
#[inline]
fn default() -> Self {
- let mut pieces: [u8; 7] = [0, 1, 2, 3, 4, 5, 6];
+ let mut pieces: [u8; 7] = [1, 2, 3, 4, 5, 6, 7];
pieces.shuffle(&mut rand::thread_rng());
Self{
index: 0,
@@ -270,7 +276,6 @@ impl Game {
}
self.figure_next[NEXT_COUNT - 1] = Figure::from_kind(self.bag.next());
(self.x, self.y) = (3, 17);
- self.stop_place_timeout();
for line in 0..FIELD_ROWS - 1 {
while self.field.is_line_complete(line) {
self.field.kill_line(line);
@@ -302,7 +307,8 @@ impl Game {
while !self.field.has_collision(&self.figure, self.x, self.y - 1) {
self.y -= 1;
}
- self.place_figure()
+ self.place_figure();
+ self.stop_place_timeout();
},
'j' => {
if !self.field.has_collision(&self.figure, self.x - 1, self.y) {
@@ -332,6 +338,7 @@ impl Game {
'h' => {
self.hold_figure();
self.reset_fall_timeout();
+ self.stop_place_timeout();
}
_ => {},
}
@@ -376,7 +383,7 @@ impl Game {
}
}
-fn print_hold(figure: &Figure, y_global: usize) {
+fn display_hold(figure: &Figure, y_global: usize) {
let offset = DISPLAY_HOLD_OFFSET_DOWN;
let at_figure = y_global >= (1 + offset) && y_global < FIGURE_SIZE_ROWS + (1 + offset);
if y_global == offset {
@@ -398,7 +405,7 @@ fn print_hold(figure: &Figure, y_global: usize) {
}
}
-fn print_next(figure: &[Figure; NEXT_COUNT], y_global: usize) {
+fn display_next(figure: &[Figure; NEXT_COUNT], y_global: usize) {
let offset = DISPLAY_NEXT_OFFSET_DOWN;
if y_global == offset {
print!(" Next: ");
@@ -422,12 +429,15 @@ fn print_next(figure: &[Figure; NEXT_COUNT], y_global: usize) {
}
}
-fn print_field(field: &Field, y: usize) {
+fn display_field(field: &Field, y: usize) {
print!("|");
for x in 0..FIELD_COLS {
- let c = field.cells[(FIELD_ROWS_VISIBLE - 1 - y) * FIELD_COLS + x];
- if c == 0 {
+ let color = field.cells[(FIELD_ROWS_VISIBLE - 1 - y) * FIELD_COLS + x] & !GHOST_MASK;
+ let ghost = field.cells[(FIELD_ROWS_VISIBLE - 1 - y) * FIELD_COLS + x] & GHOST_MASK != 0;
+ if color == 0 {
print!(" ");
+ } else if ghost {
+ print!("░░");
} else {
print!("██");
}
@@ -438,11 +448,21 @@ fn print_field(field: &Field, y: usize) {
fn display_game(game: &Game) {
cursor_to_home();
let mut field = game.field.clone();
+ let mut ghost = game.figure.clone();
+ for i in 0..FIGURE_SIZE {
+ ghost.cells[i] |= GHOST_MASK;
+ }
+ let mut y_ghost = game.y;
+ while !field.has_collision(&ghost, game.x, y_ghost) {
+ y_ghost -= 1;
+ }
+ y_ghost += 1;
+ field.render(&ghost, game.x, y_ghost);
field.render(&game.figure, game.x, game.y);
for y in 0..FIELD_ROWS_VISIBLE {
- print_hold(&game.figure_on_hold, y);
- print_field(&field, y);
- print_next(&game.figure_next, y);
+ display_hold(&game.figure_on_hold, y);
+ display_field(&field, y);
+ display_next(&game.figure_next, y);
print!("\r\x1b[1B");
}
if game.field.has_collision(&game.figure, game.x, game.y) {