Graphic by Keith Ohlfs |
PathFinderWorld |
We have a maze with either 0 or 1 bagel. We create a new
buggle and pick up its brush. Now we want the buggle to find the bagel and
draw the shortest path from the bagel back to its starting position.
The position and heading
of the buggle at the end of the exercise should be the same as at the
beginning. If the buggle found a bagel, its brush will be down at the end.
Otherwise, its brush will remain in the same state it was in before it
started trying to find the bagel. The buggle's method findBagel
returns a boolean value of true if the buggle found a bagel and
false otherwise. We can assume that the buggle has a wall to its back
when we call the findBagel
method.
What is the simplest case, our base case?
If the buggle is over a bagel when it starts, then it has found the bagel.
What if it is not the base case?
The buggle will have to search to the left, front, and right for the bagel.
It doesn't have to search behind because it starts with its back to a wall
and as it moves forward searching for bagels, it will have already searched
the cells behind it.
Searching in any direction is essentially all the same procedure.
So, if the buggle can search for a bagel in front, it should be able
to search to the left and right by turning in those directions and then
searching in front.
How do we search for a bagel in front?
This is a subproblem of the original problem so we approach it as its own problem.
What is the simplest case, our base case?
If there is a wall in front of the buggle, there can't be a bagel in front.What if it is not the base case?
The buggle will have to go forward into the cell in front to check if there is a bagel there or not. So, the buggle will go forward. How does it check if there are bagels there and/or around it? That's whatfindBagel
does. So, if the buggle callsfindBagel
it will know if there is a bagel in that cell or around it. After the buggle has found out the answer, it should return to its initial location by going backwards.
findBagel
calls findLeft
, findFront
,
and findRight
, which in turn call findBagel
findLeft
and findRight
)
public boolean findBagel() { // This method returns true if there is a bagel // to the left, front, or right of the buggle, // otherwise, it returns false. // If it returns true, it draws a path from the bagel // up to (but not including) its initial position. // The state (position and heading) of the buggle // must be left unchanged by the invocation of the method. // The buggle's brush will be down if it found a bagel // and left unchanged if it did not. if (isOverBagel()) { // base case: found the bagel brushDown(); // put the brush down return true; } else { // search for bagel in surrounding cells return findLeft() || findFront() || findRight(); } } public boolean findFront() { // This method returns true if there is a bagel // to the front of the buggle, // otherwise, it returns false. // If it returns true, it draws a path from the bagel // up to (but not including) its initial position. // The state (position and heading) of the buggle // must be left unchanged by the invocation of the method. // The buggle's brush will be down if it found a bagel // and left unchanged if it did not. if (isFacingWall()) { // base case: wall in front, no bagel return false; } else { // search for bagel starting from cell in front forward(); // go forward boolean result = findBagel(); // check if bagel here or around backward(); // undo the forward, maintain buggle state return result; } } public boolean findLeft() { // This method returns true if there is a bagel // to the left of the buggle, // otherwise, it returns false. // If it returns true, it draws a path from the bagel // up to (but not including) its initial position. // The state (position and heading) of the buggle // must be left unchanged by the invocation of the method. // The buggle's brush will be down if it found a bagel // and left unchanged if it did not. left(); boolean result = findFront(); right(); return result; } public boolean findRight() { // This method returns true if there is a bagel // to the right of the buggle, // otherwise, it returns false. // If it returns true, it draws a path from the bagel // up to (but not including) its initial position. // The state (position and heading) of the buggle // must be left unchanged by the invocation of the method. // The buggle's brush will be down if it found a bagel // and left unchanged if it did not. right(); boolean result = findFront(); left(); return result; }