From f7c560ae3eccc95f552985ff09aa725c46ff1f56 Mon Sep 17 00:00:00 2001 From: ElnuDev Date: Sat, 19 Mar 2022 13:46:38 -0700 Subject: [PATCH] Fix panicking on wall kicks, add utility Grid struct --- src/main.rs | 32 ++++++++++++++------------------ src/structs/grid.rs | 42 ++++++++++++++++++++++++++++++++++++++++++ src/structs/mod.rs | 3 +++ 3 files changed, 59 insertions(+), 18 deletions(-) create mode 100644 src/structs/grid.rs diff --git a/src/main.rs b/src/main.rs index cc9eedf..23aa90f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -57,10 +57,8 @@ fn main() { let mut block = random_block(); let mut next_block = random_block(); - // Default::default() initializes all array cells to None (no block) - let mut grid: [[Option<&TileType>; GRID_WIDTH as usize]; GRID_HEIGHT as usize] = - Default::default(); - + let mut grid = Grid::new(); + let blocks_texture = Texture::from_file(&texture("blocks")).unwrap(); let mut sprite = Sprite::with_texture(&blocks_texture); @@ -271,7 +269,7 @@ fn main() { // Check to see if new rotation state is overlapping any tiles let mut offset_required: i32 = 0; for tile in block.get_tiles().iter() { - if grid[tile.y as usize][tile.x as usize].is_some() { + if grid.get(tile.x, tile.y).is_some() { // Can't wall kick off of blocks block.rotation_state -= 1; break; @@ -306,9 +304,7 @@ fn main() { } if movement != 0 { for (i, tile) in block.get_tiles().iter().enumerate().rev() { - if tile.x + movement < 0 - || tile.x + movement >= GRID_WIDTH as i32 - || grid[tile.y as usize][(tile.x + movement) as usize].is_some() + if grid.filled(tile.x + movement, tile.y) { break; } @@ -334,7 +330,7 @@ fn main() { 'outer: loop { for tile in block.get_tiles().iter() { let y = tile.y + snap_offset; - if y >= GRID_HEIGHT as i32 || grid[y as usize][tile.x as usize].is_some() { + if grid.filled(tile.x, y) { snap_offset -= 1; break 'outer; } @@ -352,7 +348,7 @@ fn main() { // Land checking for tile in block.get_tiles().iter() { if tile.y == GRID_HEIGHT as i32 - 1 - || grid[tile.y as usize + 1][tile.x as usize].is_some() + || grid.filled(tile.x, tile.y + 1) { landed = true; break; @@ -411,13 +407,13 @@ fn main() { tiles += block.get_tiles().len() as u32; blocks += 1; for tile in block.get_tiles().iter() { - grid[tile.y as usize][tile.x as usize] = Some(&block.block_type.tile_type); + grid.set(tile.x, tile.y, Some(&block.block_type.tile_type)); } let mut cleared_lines = 0; for y in 0..GRID_HEIGHT { let mut completed = true; for x in 0..GRID_WIDTH { - if grid[y as usize][x as usize].is_none() { + if !grid.filled(x as i32, y as i32) { completed = false; break; } @@ -426,10 +422,10 @@ fn main() { continue; } for z in (0..y).rev() { - let z = z as usize; + let z = z as i32; for x in 0..GRID_WIDTH { - let x = x as usize; - grid[z + 1][x] = grid[z][x]; + let x = x as i32; + grid.set(x, z + 1, grid.get(x, z)); } } cleared_lines += 1; @@ -466,12 +462,12 @@ fn main() { row_clear_sound.play(); } for tile in next_block.get_tiles().iter() { - if grid[tile.y as usize][tile.x as usize].is_some() { + if grid.filled(tile.x, tile.y) { score = 0; lines = 0; blocks = 0; tiles = 0; - grid = Default::default(); // reset grid + grid.clear(); update_interval = get_update_interval(0); game_over_sound.play(); next_block = random_block(); @@ -487,7 +483,7 @@ fn main() { // Drawing grid for y in 0..GRID_HEIGHT { for x in 0..GRID_WIDTH { - let tile_type = grid[y as usize][x as usize]; + let tile_type = grid.get(x as i32, y as i32); if tile_type.is_none() { continue; } diff --git a/src/structs/grid.rs b/src/structs/grid.rs new file mode 100644 index 0000000..8d455fb --- /dev/null +++ b/src/structs/grid.rs @@ -0,0 +1,42 @@ +use crate::config::*; +use crate::structs::TileType; + +pub struct Grid<'a> { + grid: [[Option<&'a TileType>; GRID_WIDTH as usize]; GRID_HEIGHT as usize], +} + +impl<'a> Grid<'a> { + pub fn new() -> Self { + Self { + grid: Default::default() + } + } + + pub fn out_of_bounds(&self, x: i32, y: i32) -> bool { + x < 0 || x >= GRID_WIDTH as i32 || y < 0 || y >= GRID_HEIGHT as i32 + } + + pub fn get(&self, x: i32, y: i32) -> Option<&'a TileType> { + if self.out_of_bounds(x, y) { + None + } else { + self.grid[y as usize][x as usize] + } + } + + // Checks if a coordinate is filled, either by a tile or out of bounds space + // For checking if there is a tile specifically, do .get(x, y).is_some() + pub fn filled(&self, x: i32, y: i32) -> bool { + self.out_of_bounds(x, y) || self.get(x, y).is_some() + } + + pub fn set(&mut self, x: i32, y: i32, tile_type: Option<&'a TileType>) { + if !self.out_of_bounds(x, y) { + self.grid[y as usize][x as usize] = tile_type; + } + } + + pub fn clear(&mut self) { + self.grid = Default::default(); + } +} \ No newline at end of file diff --git a/src/structs/mod.rs b/src/structs/mod.rs index abce96a..6831c7d 100644 --- a/src/structs/mod.rs +++ b/src/structs/mod.rs @@ -9,3 +9,6 @@ pub use tile_type::TileType; mod number_renderer; pub use number_renderer::NumberRenderer; + +mod grid; +pub use grid::Grid;