A maze search needs a value for each position it visits. `MazeLocation` stores that position as an integer row and column. It is a custom struct rather than a tuple because search data structures need hashable states. section 2.2
struct MazeLocation: Hashable {
let row: Int
let col: Int
var hashValue: Int { return row.hashValue ^ col.hashValue }
}
func == (lhs: MazeLocation, rhs: MazeLocation) -> Bool {
return lhs.row == rhs.row && lhs.col == rhs.col
}
The struct defines `row`, `col`, a hash value, and equality based on both coordinates. section 2.2
A goal test compares a location with the goal at `(9, 9)`. Successor generation checks the four adjacent positions, excluding maze edges and blocked cells. The resulting locations can be searched and marked as a path through the maze. section 2.2
