diff --git a/maze/src/lib.rs b/maze/src/lib.rs index eb44ff2..8a2d399 100644 --- a/maze/src/lib.rs +++ b/maze/src/lib.rs @@ -275,6 +275,37 @@ where )) } + /// All walls that meet in the corner where a wall has its end span. + /// + /// The walls are visited in clockwise order. Only one side of each wall + /// will be visited. Each consecutive wall will be in a room different from + /// the previous one. + /// + /// This method will visit rooms outside of the maze for rooms on the edge. + /// + /// # Arguments + /// * `wall_pos` - The wall position. + pub fn corner_walls_rev( + &self, + wall_pos: WallPos, + ) -> impl Iterator + DoubleEndedIterator { + let shape = self.shape; + let (matrix::Pos { col, row }, wall) = shape.back(wall_pos); + std::iter::once(wall_pos).chain( + wall.corner_wall_offsets.iter().rev().map( + move |&wall::Offset { dx, dy, wall }| { + shape.back(( + matrix::Pos { + col: col + dx, + row: row + dy, + }, + wall, + )) + }, + ), + ) + } + /// Iterates over all wall positions of a room. /// /// # Arguments @@ -485,12 +516,24 @@ mod tests { #[maze_test] fn corner_walls(maze: TestMaze) { for pos in maze.positions() { - for wall in maze.walls(pos) { - let wall_pos = (pos, *wall); + for wall_pos in maze.wall_positions(pos) { let (center, _) = maze.corners(wall_pos); for corner_wall in maze.corner_walls(wall_pos) { - let (start, end) = maze.corners(corner_wall); - assert!(is_close(start, center) || is_close(end, center)); + let (corner, _) = maze.corners(corner_wall); + assert!(is_close(corner, center)); + } + } + } + } + + #[maze_test] + fn corner_walls_rev(maze: TestMaze) { + for pos in maze.positions() { + for wall_pos in maze.wall_positions(pos) { + let (_, center) = maze.corners(wall_pos); + for corner_wall in maze.corner_walls_rev(wall_pos) { + let (_, corner) = maze.corners(corner_wall); + assert!(is_close(corner, center)); } } }