You're a blind adventurer (bad luck eh). To go through the maze that'll lead you to freedom, you must first find the maze's wall, then follow this wall to find the maze's entry. Then, to get an idea about the size of the maze, you want to see how large is the said entry, so you walk until you touch another wall, which is the other border of the entrance. Still following? If not, here's a boolean[][]
that'll show my example :
1,1,1,1,1,0,0,0,1,1,1,1,1
0,0,0,1,1,0,0,0,1,1,0,0,0
- Zeros implies there is no wall
- Ones implies there is a wall.
The entry of the maze can be found on the last index of the array, meaning :
maze[x,maze.length-1]
In my example, the entrance is found at [6,1]
. As it is a first iteration, the maze is expected to have only one entry, which is valid, which will be situated on the last row of the array. @DoubleDouble already pointed out a flaw of my algorithm in his answer.
If the maze contained an even number of "columns", the entrance could be either the "left" or "right", it doesn't matter.
To find the entrance to my maze, I wrote the function guessEntry
, in my Maze
class :
package com.mazr.domain;
import java.awt.Point;
public class Maze {
private boolean[][] content;
public Maze(boolean[][] content) {
this.content = content;
}
public Point guessEntry() throws InvalidMazeException {
int openingBorder, closingBorder;
int xIndex = 0;
final int bottomYIndex = content[0].length-1;
try {
//Find the wall
while (!content[xIndex][bottomYIndex])
xIndex++;
//Follow the wall to the entry
while (content[xIndex][bottomYIndex])
xIndex++;
openingBorder = xIndex;
//Follow the entry until the end of it
while (!content[xIndex][bottomYIndex])
xIndex++;
closingBorder = xIndex;
return new Point((closingBorder - openingBorder) / 2, bottomYIndex);
}
catch(IndexOutOfBoundsException e){
throw new InvalidMazeException("The maze has no guessable entry", e);
}
}
}
To make the example even clearer, I will show how the algorithm behaves to find an entrance (Don't forget that it only works on the bottom row of the array, which is assumed to contain some walls.):
//Find the wall
while (!content[xIndex][bottomYIndex])
xIndex++;
0,0,0,1,1,0,0,0,1,1,0,0,0
------^
xIndex
is now at this position, since it went through all the left zeroes.
//Follow the wall to the entry
while (content[xIndex][bottomYIndex])
xIndex++;
0,0,0,1,1,0,0,0,1,1,0,0,0
----------^
xIndex
is now there, since it went through the first wall. We setopeningBorder
toxIndex
since this is the beginning of the entrance "hall".
//Follow the entry until the end of it
while (!content[xIndex][bottomYIndex])
xIndex++;
0,0,0,1,1,0,0,0,1,1,0,0,0
----------------^
xIndex
went to the next wall, which marks the end of the entrance "hall". We set theclosingBorder
toxIndex
so we can know where is the hall situated.
Then, averaging (sorry if that's not a word) the closing and opening border, we can figure out where is the middle of the hall, so we can start solving it (in an upcoming question).
The jagged array is rectangular, meaning that wether we talk about index 0 or 1732, the jagged array will have the same length.
Now, it is easy to seek why I need a review. The function works, it is arguably easy to understand. But I can't stand these following while
loops..
I'm using Java 1.8.
I know I'm providing only one method, but I feel like it is already hard to explain briefly and to be clear about the cases.
[2][13]
array or a[13][2]
array? Your example looks like[2][13]
but your code looks like it expects[13][2]
otherwise it would not return(1,6)
as you stated. \$\endgroup\$[6,1]
as the entrance instead of[1,6]
. \$\endgroup\$[x][y]
order, but normally, most people keep their 2-D arrays in[row][column]
order, which would be reverse of how you do it. Maybe that is where the confusion comes from. Either way works, of course. \$\endgroup\$