A maze search needs to know where it can go next. Given a MazeLocation, successors returns an array of reachable neighboring locations. Movement is one space up, down, left, or right—never diagonally. section 2.2
For each candidate neighbor:
- Check that its row or column stays within the maze. section 2.2
- Add it only if its cell is not blocked. section 2.2
func successorsForMaze(_ maze: Maze) -> (MazeLocation) -> [MazeLocation] {
func successors(ml: MazeLocation) -> [MazeLocation] { //no diagonals
var newMLs: [MazeLocation] = [MazeLocation]()
if (ml.row + 1 < maze.count) && (maze[ml.row + 1][ml.col] != .Blocked) {
newMLs.append(MazeLocation(row: ml.row + 1, col: ml.col))
}
if (ml.row - 1 >= 0) && (maze[ml.row - 1][ml.col] != .Blocked) {
newMLs.append(MazeLocation(row: ml.row - 1, col: ml.col))
}
if (ml.col + 1 < maze[0].count) && (maze[ml.row][ml.col + 1] != .Blocked) {
newMLs.append(MazeLocation(row: ml.row, col: ml.col + 1))
}
if (ml.col - 1 >= 0) && (maze[ml.row][ml.col - 1] != .Blocked) {
newMLs.append(MazeLocation(row: ml.row, col: ml.col - 1))
}
return newMLs
}
return successors
}
The Swift implementation returns successors from successorsForMaze. The inner function captures the maze, so callers can pass a maze-specific neighbor function to a search algorithm. section 2.2
Depth-first search, breadth-first search, and A* accept this function as successorFn. An alternative design would make successors a method on a Maze class. section 2.2
