diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/main.rs | 64 |
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) { |