successorsForMaze builds a maze-specific successor function. The returned function accepts a MazeLocation and lists reachable horizontal or vertical neighbors, excluding walls and positions outside the maze. 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 implementation returns a closure that captures the maze, checks four directions, rejects blocked cells, and returns valid MazeLocation values. section 2.2
Supplying a search with maze successors
Pass successorsForMaze(maze) as successorFn when invoking a generic search such as dfs, bfs, or astar. Each algorithm can then explore the same maze representation through its captured successor function. section 2.2
The function’s behavior depends on these design choices:
- Moves only one space horizontally or vertically; diagonal movement is omitted. section 2.2
- Captures the maze from the outer function, avoiding repeated maze arguments during search. section 2.2
- Could be replaced by a Maze type with a successors method; both styles suit Swift’s functional and object-oriented flexibility. section 2.2
