refactor: `map.at` now returns `Option<&Tile>` rather than a wall tile when requested coordinates are out-of-bounds.

This commit is contained in:
Nolan Darilek 2022-05-19 13:14:12 -05:00
parent 56884ead38
commit 1fa4ba6b26
4 changed files with 38 additions and 32 deletions

View File

@ -130,12 +130,12 @@ mod tests {
let gen = BspInterior::<NoData>::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());
}
}
}

View File

@ -150,8 +150,12 @@ impl<D: Clone + Default> BspRooms<D> {
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::<NoData>::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());
}
}
}

View File

@ -76,7 +76,7 @@ fn apply_iteration<D: Clone + Default>(map: &Map<D>) -> Map<D> {
];
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::<NoData>::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());
}
}

View File

@ -112,13 +112,9 @@ impl<D: Clone + Default> Map<D> {
}
/// 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<D: Clone + Default> Map<D> {
// 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<D: Clone + Default> Map<D> {
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<D: Clone + Default> fmt::Display for Map<D> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
for y in 0..self.height {
let bytes: Vec<u8> = (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::<NoData>::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());
}
}
}