# Lecture 24: More Mazes

## How Can We Solve Mazes?

Suggested strategy:

• Store visited cells
• Pick a direction, and go until dead end
• walled in, or have already visited neighbors
• Backtrack until you see an unvisited neighboring node
• Continue in new direction

This strategy is depth-first

• Go as far as possible and backtrack

## In More Detail

• fix an order on possible neighbors of cells
• e.g., right, down, left, up
• when visiting a cell:
• mark it as visited
• check if it is the goal
• if not, visit “next” unvisited neighbor
• if no unvisited neighbors, return to “parent” cell

## Representing a Maze in Code

• Cell class stores (among other things)
• list of references to neighboring Cells (those not separated by walls)
• Maze class stores
• 2d array of Cells
• start and goal cells

## How to Implement Solution?

• Store visited cells (How?)
• Store active cells (How?)
• not yet exhausted
• forms path back to start

## Implementing Our Solution Strategy

• use an ArrayList to keep track of visited cells
• use a stack to keep track of active cells
• active cells form a path from start to current cell
• when we visit a new cell, push it to the stack
• when we’ve explored all neighbors (and haven’t found the goal):
• pop current cell off stack
• return to previous cell on stack—cell from which we initially visited current cell

## Recursion: Our Old Friend

Use a stack an find goal recursively

• write method boolean solve (Stack<Cell> active, ArrayList<Cell> visited) {...}

How?

## Stack-based solution

• idea: try to find goal from current cell (top of active)
• if current is goal, return true
• otherwise, find goal from unvisited neighbors:
• push neighbor onto active stack and add neighbor to visited
• call solve to continue exploration from new neighbor
• if recursive call to solve returns true, we should return true too
• if exploration fails to find anything pop current off stack and return false

When goal is found, active will contain the path from start to goal

## Question

Some of our solutions were really inefficient!

• goal could be adjacent to start, but a much longer path from start to goal is found

How could we ensure that we find the shortest path from start to goal?

## Another Strategy

Explore in all directions simultaneously!

• Consider all possible first steps
• Then all possible second steps
• ignore previously visited cells

This strategy is breadth first

• Explore all possible next steps

## A Nice Feature

The shortest path from start to goal is found

• why?

## Implementation Notes

• again, store visited and active
• active cells are boundary between visited and unvisited
• store active cells in a queue
• all cells at distance $d$ from start are visited before any cell at distance $d+1$ is visited
• initially, active and visited are just starting cell
• each cell stores its parent cell
• parent is cell from which cell was visited