public boolean findSolution() {
boolean finish = false; //finish should become true when a solution is found or it is determined that there is no solution
boolean success = false; //success should become true when a solution is found
//The following can be used to compute each of 8 directions
//one can move from their current position (row,column).
int[][] offset ={
{1,0}, //Down
{1,-1}, //DownLeft
{0,-1}, //Left
{-1,-1}, //UpLeft
{-1,0}, //Up
{-1,1}, //UpRight
{0,1}, //Right
{1,1} //DownRight
};
//Push information onto the stack indicating the first choice
//is the position of row 0 and column 9. The last value is face, put -1 as default
Position nextPosition = new Position(0, 9, -1);
stackSoln.push(nextPosition);
while (finish == false && stackSoln.isEmpty( ) == false) {
//check the last position
int currentRow = stackSoln.peek().getRow();
int currentCol = stackSoln.peek().getColumn();
System.out.println("Trying the position of row "
+ currentRow
+ " and column "
+ currentCol);
int newRow = -1;
int newColumn=-1;
for (int k = 0; k < 8; k++)
{
newRow = currentRow + offset[k][0];
newColumn = currentCol + offset[k][1];
//get a new position and push it
nextPosition = new Position(newRow, newColumn, -1);
stackSoln.push(nextPosition);
if (newRow < 9 && newColumn < 9 && newRow > 0 &&
newColumn > 0 && (maze[newRow][newColumn] == 'x' &&
maze[newRow][newColumn] == '.' ||
maze[newRow][newColumn] == '<' || maze[newRow][newColumn] ==
'>'))
{
if (maze[newRow][newColumn] == '<') //end of the maze
{
nextPosition.setFace(k);
success = true;
finish = true;
}
else if (maze[newRow][newColumn] == '.') //able to move
{
maze[newRow][newColumn] = 'x';
nextPosition.setFace(k);
break;
}
else
{
maze[newRow][newColumn] = 'O'; //unable to move, therefore pop the position.
stackSoln.pop();
}
if (stackSoln.isEmpty() == true)
{
success = false;
finish = true;
}
}
}
} //end of while loop
return success;
}//end of findSolution method
Given input like this: https://i.sstatic.net/h3s1C.png
It is supposed to return:
Trying the position of row 0 and column 9
Trying the position of row 1 and column 8
Trying the position of row 2 and column 7
Trying the position of row 3 and column 7
Trying the position of row 4 and column 7
Trying the position of row 4 and column 6
Trying the position of row 5 and column 5
Trying the position of row 4 and column 4
Trying the position of row 5 and column 3
Trying the position of row 6 and column 3
Trying the position of row 7 and column 3
Trying the position of row 8 and column 3
Trying the position of row 9 and column 2
Trying the position of row 9 and column 1
But instead, my code does something like:
Trying the position of row 59834 and column 59843
Trying the position of row 59835 and column 59844
Trying the position of row 59836 and column 59845...etc
For some reason if I change the main if statement in the for loop to ors instead of ands, it gets the right values up to the last one where it then gets an index out of bounds error. I have no idea why though because ors shouldn't be used in this situation...
The problem is that you're pushing new positions onto the stack before checking that the row and column are valid.
Look at these lines in your code:
//get a new position and push it
nextPosition = new Position(newRow, newColumn, -1);
stackSoln.push(nextPosition);
Instead of pushing nextPosition
onto the stack immediately, wait until you've validated the position.
You probably want to push the position onto the stack inside the block guarded by this if
statement:
if (newRow <= 9 && newColumn <= 9 && newRow > 0 &&
newColumn > 0 && (maze[newRow][newColumn] == 'x' &&
maze[newRow][newColumn] == '.' ||
maze[newRow][newColumn] == '<' || maze[newRow][newColumn] ==
'>'))
However, there are some problems with the conditional expression. You should accept zero values for newRow
and newColumn
. Also, the part where you check the character in the maze is complicated and incorrect because you're mixing &&
with ||
and because you're not accounting for the O
characters that you're putting into the maze.
I suggest that you use this expression instead:
if (newRow >= 0 && newRow < mazeSize &&
newColumn >= 0 && newColumn < mazeSize &&
maze[newRow][newColumn] != '#')
Note that it's better to use the class attribute mazeSize
instead of a hard-coded value. This allows the expression to work for different maze sizes.
There are further problems in your code that fall outside the scope of this question.