From 1fa4ba6b26cc8c8e2dd83904da9718770fcf9bc6 Mon Sep 17 00:00:00 2001 From: Nolan Darilek Date: Thu, 19 May 2022 13:14:12 -0500 Subject: [PATCH] refactor: `map.at` now returns `Option<&Tile>` rather than a wall tile when requested coordinates are out-of-bounds. --- src/filter/bsp_interior.rs | 8 +++---- src/filter/bsp_rooms.rs | 16 ++++++++----- src/filter/cellular_automata.rs | 6 ++--- src/map.rs | 40 +++++++++++++++++---------------- 4 files changed, 38 insertions(+), 32 deletions(-) diff --git a/src/filter/bsp_interior.rs b/src/filter/bsp_interior.rs index 8a7b504..7cc7f4c 100644 --- a/src/filter/bsp_interior.rs +++ b/src/filter/bsp_interior.rs @@ -130,12 +130,12 @@ mod tests { let gen = BspInterior::::new(); let map = gen.modify_map(&mut rng, &Map::new(80, 50)); for i in 0..80 { - assert!(map.at(i, 0).is_blocked()); - assert!(map.at(i, 49).is_blocked()); + assert!(map.at(i, 0).unwrap().is_blocked()); + assert!(map.at(i, 49).unwrap().is_blocked()); } for j in 0..50 { - assert!(map.at(0, j).is_blocked()); - assert!(map.at(79, j).is_blocked()); + assert!(map.at(0, j).unwrap().is_blocked()); + assert!(map.at(79, j).unwrap().is_blocked()); } } } diff --git a/src/filter/bsp_rooms.rs b/src/filter/bsp_rooms.rs index 0fe4a8b..9c3da49 100644 --- a/src/filter/bsp_rooms.rs +++ b/src/filter/bsp_rooms.rs @@ -150,8 +150,12 @@ impl BspRooms { if y < 1 { can_build = false; } - if can_build && map.at(x as usize, y as usize).is_walkable() { - can_build = false; + if can_build { + if let Some(tile) = map.at(x as usize, y as usize) { + if tile.is_walkable() { + can_build = false; + } + } } } } @@ -174,12 +178,12 @@ mod tests { let gen = BspRooms::::new(); let map = gen.modify_map(&mut rng, &Map::new(80, 50)); for i in 0..80 { - assert!(map.at(i, 0).is_blocked()); - assert!(map.at(i, 49).is_blocked()); + assert!(map.at(i, 0).unwrap().is_blocked()); + assert!(map.at(i, 49).unwrap().is_blocked()); } for j in 0..50 { - assert!(map.at(0, j).is_blocked()); - assert!(map.at(79, j).is_blocked()); + assert!(map.at(0, j).unwrap().is_blocked()); + assert!(map.at(79, j).unwrap().is_blocked()); } } } diff --git a/src/filter/cellular_automata.rs b/src/filter/cellular_automata.rs index 8526928..1722686 100644 --- a/src/filter/cellular_automata.rs +++ b/src/filter/cellular_automata.rs @@ -76,7 +76,7 @@ fn apply_iteration(map: &Map) -> Map { ]; let neighbors = idxs .iter() - .filter(|(x, y)| map.at(*x, *y).is_blocked()) + .filter(|(x, y)| map.at(*x, *y).unwrap().is_blocked()) .count(); if neighbors > 4 || neighbors == 0 { @@ -103,7 +103,7 @@ mod tests { fn test_iteration_wal() { let map = Map::::new(3, 3); let new_map = apply_iteration(&map); - assert!(new_map.at(1, 1).is_blocked()); + assert!(new_map.at(1, 1).unwrap().is_blocked()); } #[test] @@ -115,6 +115,6 @@ mod tests { } } let new_map = apply_iteration(&map); - assert!(new_map.at(1, 1).is_walkable()); + assert!(new_map.at(1, 1).unwrap().is_walkable()); } } diff --git a/src/map.rs b/src/map.rs index 72d4d74..75b8f6d 100644 --- a/src/map.rs +++ b/src/map.rs @@ -112,13 +112,9 @@ impl Map { } /// Get TileType at the given location - pub fn at(&self, x: usize, y: usize) -> Tile { - if x >= self.width || y >= self.height { - Tile::wall() - } else { - let idx = (y as usize) * self.width + (x as usize); - self.tiles[idx] - } + pub fn at(&self, x: usize, y: usize) -> Option<&Tile> { + let idx = (y as usize) * self.width + (x as usize); + self.tiles.get(idx) } /// Get available exists from the given tile @@ -158,7 +154,11 @@ impl Map { // Check if given tile can be accessed fn is_exit_valid(&self, x: usize, y: usize) -> bool { - !self.at(x, y).is_blocked + if let Some(tile) = self.at(x, y) { + !tile.is_blocked + } else { + false + } } /// Modify tile at the given location @@ -200,9 +200,11 @@ impl Map { y -= 1; } - if self.at(x, y).is_blocked { - corridor.push(Point::new(x, y)); - self.set_tile(x, y, Tile::floor()); + if let Some(tile) = self.at(x, y) { + if tile.is_blocked { + corridor.push(Point::new(x, y)); + self.set_tile(x, y, Tile::floor()); + } } } } @@ -274,7 +276,7 @@ impl fmt::Display for Map { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { for y in 0..self.height { let bytes: Vec = (0..self.width) - .map(|x| if self.at(x, y).is_blocked { '#' } else { ' ' } as u8) + .map(|x| if self.at(x, y).unwrap().is_blocked { '#' } else { ' ' } as u8) .collect(); let line = String::from_utf8(bytes).expect("Can't convert map to string"); let _ = writeln!(f, "{}", line); @@ -295,7 +297,7 @@ mod tests { let map = Map::::new(10, 10); for i in 0..10 { for j in 0..10 { - assert!(map.at(i, j).is_blocked); + assert!(map.at(i, j).unwrap().is_blocked); } } } @@ -312,12 +314,12 @@ mod tests { assert_eq!(map.width, 10); assert_eq!(map.height, 3); for i in 0..10 { - assert!(map.at(i, 0).is_blocked); - assert!(map.at(i, 2).is_blocked); + assert!(map.at(i, 0).unwrap().is_blocked); + assert!(map.at(i, 2).unwrap().is_blocked); if i == 0 || i == 9 { - assert!(map.at(i, 1).is_blocked); + assert!(map.at(i, 1).unwrap().is_blocked); } else { - assert!(map.at(i, 1).is_walkable()); + assert!(map.at(i, 1).unwrap().is_walkable()); } } } @@ -343,9 +345,9 @@ mod tests { for x in 0..map.width { for y in 0..map.height { if x == 0 || y == 0 || x == 4 || y == 4 { - assert!(map.at(x, y).is_blocked); + assert!(map.at(x, y).unwrap().is_blocked); } else { - assert!(map.at(x, y).is_walkable()); + assert!(map.at(x, y).unwrap().is_walkable()); } } }