How to end my recursion - java

I need to program a method to solve a maze (2-dimensional array). I need to stay directly left of the wall at all times and my method should end when either I've reached the exit point (which is always at the same position) or when there is no solution possible (and, after running through the maze I'm back at the entry point).
I was able to do all that, no problems, I can visually ensure that it's doing what I want it to do (we've got some other methods from our instructor which output the visuals) and my console debug output is right as well.
This is the relevant code:
public static void main(String[] args) {
maze = generateMaze(10,10);
walk(1,0,0);
}
public static void walk(int x, int y, int direction) {
System.out.println("x = " + x + " y = " + y); //debug output
draw(x,y,maze); //draws current position
if (x == maze.length-1 && y == maze[1].length-2) { //terminate when reached exit
System.out.println("Geschafft!");
return;
}
if (x == 1 && y == 0 && direction == 3) { //terminate when at starting point again (no solution)
System.out.println("Keine Lösung möglich.");
return;
}
if (direction == 0) { //go down
if (maze [x][y+1]) {
walk(x,y,1);
}
walk(x,y+1,2);
}
if (direction == 1) { //go right
if(maze [x+1][y]) {
walk(x,y,3);
}
walk(x+1,y,0);
}
if (direction == 2) { //go left
if(maze [x-1][y]) {
walk(x,y,0);
}
walk(x-1,y,3);
}
if (direction == 3) { //go up
if(maze[x][y-1]) {
walk(x,y,2);
}
walk(x,y-1,1);
}
}
There's just one problem: how do I end my recursion correctly? This is what I get form the console:
x = 1 y = 0
x = 1 y = 1
x = 1 y = 1
x = 1 y = 2
and so on...
x = 8 y = 8
x = 9 y = 8
Geschafft!
x = 8 y = 9
x = 8 y = 9
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 10
at maze.MazeSolution.walk(MazeSolution.java:26)
at maze.MazeSolution.walk(MazeSolution.java:39)
and some more of that
I do understand the error, the recursion obviously doesn't end where I want it to and x or y are increased and try to use an index in the array that isn't there.
Why doesn't the recursion end with the return statement, when either of these situations come true:
if (x == maze.length-1 && y == maze[1].length-2) { //terminate when reached exit
System.out.println("Geschafft!");
return;
}
if (x == 1 && y == 0 && direction == 3) { //terminate when at starting point again (no solution)
System.out.println("Keine Lösung möglich.");
return;
}
What do I need to do to end it correctly?
I greatly appreciate your help, show some love for a beginner and tell me what to do.

Add to the beginning
public static void walk(int x, int y, int direction) {
System.out.println("x = " + x + " y = " + y); //debug output
if (x >= 10 || x < 0 || y >= 10 || y < 0) return;

Look at your returns and where you may return to. You can return in the middle of your enclosing function which has other calls to walk, without the guards to ensure they're not called.
I recommend re-implementing your logic; think about having if/else pairs to ensure mutual exclusion.

Why don't you simply return true or false and react on it?
So basically you add to your two end cases return true; for code ended.
if(walk(...)) return true;

Related

Exception in thread "AWT-EventQueue-0" java.lang.ArithmeticException: / by zero in part of the program where it should divide numbers

I tried searching stackoverflow for answer but i could not find it. i figured out when i remove part of the program that divides numbers:
if(znak == 0) {
Resenje = x + y;
}else if(znak == 1) {
Resenje = x - y;
}else if(znak == 2) {
Resenje = x/y;
} else if(znak == 3) {
Resenje = x*y;
}else {
System.out.println("Greska u programu");
}
that error does not appear. i think the problem maybe if number is float but it is stored in int... Thank you, if you need any additional information im here to provide it.. :)
PS code is messy because i made it long time ago.. sorry, i cant figure out how to properly format it, i posted it on pastebin, i hope you dont mind it.. :)
https://pastebin.com/sfG9JEbR link for code
while(vece = true) {
// System.out.println(Odabir1);
x = random.nextInt(Odabir1);
// System.out.println(x);
y = random.nextInt(Odabir1);
// System.out.println(y);
//if(x == (int)x) {
if(x-y >= 0 && x+y <= Odabir1 && x+y!=0 && x-y!=0 && x/y >= 0 && x/y == (int)x && x*y >= 0 && x*y <= Odabir1) {
System.out.println(x + " " + y);
break;
}
}
when i try adding && y == 0; i get same error in every possibility

What is wrong with my Java recursive function?

I'm trying to write a relatively straightforward recursive program in Java to compute all the possible ways to traverse a 4x4 matrix (not necessarily traveling through every spot), starting at the top left and ending in the bottom right spaces. I use a 2-D array to do this, marking off visited spaces with "1"s as I go.
It's been a while since I've worked recursively and I can't seem to get the output I expect. The output from the code below is "2" - obviously, the result should be much higher. I know there's something tiny I'm overlooking. Can someone tell me what it is?
public static void main(String[] args) {
int[][] matrix = new int[4][4];
int result = moveRobot(matrix, 0, 0);
System.out.print(result + "");
}
public static int moveRobot(int[][] matrix, int x, int y) {
if (x == 3 && y == 3) {
return 1;
} else if (x < 0 || y < 0 || x > 3 || y > 3) {
return 0;
} else if (matrix[x][y] == 1) {
return 0;
} else {
matrix[x][y] = 1;
return moveRobot(matrix, x, y+1) + moveRobot(matrix, x+1, y) + moveRobot(matrix, x, y-1) +
moveRobot(matrix, x-1, y);
}
}
The problem is that the matrix is not copied but passed by value of the reference to it. Every time you modify it such in matrix[x][y] = 1 other successive code paths will see the modification instead that working on an unmodified state.
For example here:
moveRobot(matrix, x, y+1) + moveRobot(matrix, x+1, y)
Entering the first call will modify matrix, so in second moveRobot call you'd end up with 1 in matrix[x][y+1] while that's not what you want.

Avoid out of bounds exception in 2D array

I'm trying to solve a problem which uses a 2D array, the problem of a rat in a maze.
While checking the conditions trying to compile, it finds an Array index out of bounds exception... how can I check the values so it doesn't go out of the array bounds?
static void solveMaze(){
int nSteps = 0; // Number of steps.
int x = 0; int y = 0; // Starting point.
boolean mazeCompleted = false;
while (!mazeCompleted){
if(x == maze.mazeMatrix.length && y == maze.mazeMatrix.length)
mazeCompleted = true;
else if(maze.mazeMatrix[x+1][y] == 0){ // Move right.
maze.mazeMatrix[x+1][y] = 2;
x++; nSteps++;
}
else if(maze.mazeMatrix[x-1][y] == 0){ // Move left.
maze.mazeMatrix[x-1][y] = 2;
x--; nSteps++;
}
else if(maze.mazeMatrix[x][y+1] == 0){ // Move down.
maze.mazeMatrix[x][y+1] = 2;
y++; nSteps++;
}
else if(maze.mazeMatrix[x][y-1] == 0){ // Move up.
maze.mazeMatrix[x][y-1] = 2;
y--; nSteps++;
}
}
maze.printMatrix();
System.out.println("Maze COMPLETE! - With a total of " + nSteps + " steps.");
}
Tried before with two "for" loops to prevent the out of bounds but I just can't go diagonal in this problem.
You have a pretty crucial bug in your program. You will never reach the end of the maze!
if(x == maze.mazeMatrix.length && y == maze.mazeMatrix.length)
references indices that are out of bounds! It should be
if(x == maze.mazeMatrix.length - 1 && y == maze.mazeMatrix.length - 1)
You also need to check to see whether you can & should move before you try to move there. I.E. :
while (!mazeCompleted){
boolean moveRight = (x + 1 < mazeMatrix.length && maze.mazeMatrix[x+1][y] == 0 ? true : false);
boolean moveLeft = (x - 1 >= 0 && maze.mazeMatrix[x-1][y] == 0 ? true : false);
boolean moveUp = (y + 1 < mazeMatrix[x].length && maze.mazeMatrix[x][y+1] == 0 ? true : false);
boolean moveDown = (y - 1 >= 0 && maze.mazeMatrix[x][y-1] == 0 ? true : false);
And:
else if(moveRight) { // Move right.
maze.mazeMatrix[x+1][y] = 2;
x++; nSteps++;
}
etc. Although it does seem like this is something that should be solved recursively, as if there are any loops in the maze you will end up getting stuck and infinite looping.

basic recursive backtracking (robot 2D pathfinding)

I'm working on a practice problem and is stuck. The problem asks to write a method that takes in two integers x and y to print all solutions for traveling in the 2D plane from (0,0) to (x,y) by repeatedly using one of three moves:
move right 1 (E)
move up 1 (N)
move right 1 and up 1 (NE)
These are some example calls:
call: travel(2, 1)
output: E E N // E N E // E NE // N E E // NE E
I wrote the following code:
public void travel(int x, int y) {
if (x == 0 && y == 0) {
System.out.println();
} else if (x > 0 && y > 0) {
System.out.print("E ");
travel(x-1, y);
System.out.print("N ");
travel(x, y-1);
System.out.print("NE ");
travel(x-1, y-1);
} else if (x > 0 && y == 0) {
System.out.print("E ");
travel(x-1, y);
} else if (y > 0 && x == 0) {
System.out.print("N ");
travel(x, y-1);
}
}
Calling the above method results in the following code:
call: travel(2,1);
output: E E N // N E // NE // N E E // NE E
I know that for this example call the problem lies with the E only getting printed once for three different cases that require E because the E is printed before the subsequent recursive methods are called.
I would like to fix this (without certainty that this is the right approach) by attaching the System.out.print command with each calling of the travel method. That way whenever travel method is called the result is printed with the first letter every time. However, since the method doesn't return anything, I can't insert the method within the print statement. This is where I've been stuck for a long time.
Any advice on how to go from here would be appreciated.
When recursively building solutions, it's common to pass a partially built solution as an argument to the recursive call.
public void travel(int x, int y, String path) {
if (x == 0 && y == 0) {
System.out.println(path);
} else if (x > 0 && y > 0) {
travel(x-1, y, path + ' E');
travel(x, y-1, path + ' N');
travel(x-1, y-1, path + ' NE');
} else if (x > 0 && y == 0) {
travel(x-1, y, path + ' E');
} else if (y > 0 && x == 0) {
travel(x, y-1, path + ' N');
}
}
See how we build the path as we go along - and let the function calls handle the complexity of remembering where we are in the search? This also has the nice property of simplifying our code, since we get exactly one call to System.out.println per path.

Recursive Back tracking in a maze in java

Hi im new to the site so sorry if this is a repeat question but none of the previous questions seemed to match mine
I'm practising search algorithms within a maze structure and my attempt at a recursive backtracking is not working
Basically I have followed a exercise on a book Dietel volume 7 to create a maze and use recursion to find the solution but all my code does is:
finds the start position.
gets to the next position
then says there is no other move and exits the program
This is my method its know its bulky but im still working on it
public boolean mazeTraversal( char maze2[][], int x, int y)
{
lastX = x;
lastY = y;
maze[ x ][ y ] = 'x';
printMaze();
showPosition();
showMoves();
System.out.println("Press the key 'g' to traverse the maze : ");
move++;
if((x == Y_START) && (x == X_START) && (move > 1))
{
System.out.println("You have gone back to the start");
return false;
}
else if ( mazeExited( x, y ) && ( move > 1 ) )
{
System.out.println("You have reached the end");
return true;
}
else
{
char response = scanner.nextLine().charAt( 0 );
showPosition();
showMoves();
System.out.println( "Enter 'g' to continue, 'e' to exit: " );
if(response == 'e')
{
System.exit(0);
}
if(response == 'g')
while(checkMaze(x,y) == validMove(x,y) && checkMaze(x,y)!= mazeExited(x,y))
{
for(int count = 0; count < 4; count++)
{
switch (count)
{
case (DOWN):
if ( validMove( x + 1, y ) )
{
mazeTraversal(maze2, x + 1, y);
}
break;
case (RIGHT):
if ( validMove( x, y + 1 ) )
{
mazeTraversal( maze2, x, y + 1 );
}
break;
case (UP): // move up
if ( validMove( x - 1, y ) )
{
mazeTraversal( maze2, x - 1, y );
}
break;
case (LEFT): // move left
if ( validMove( x, y - 1 ) )
{
mazeTraversal( maze2, x, y - 1 );
}
}
}
}
}
return false;
}
Any pointers would be great.
Thanks Mike
I would consider returning your recursive calls to mazeTraversal() in your else block, instead of returning false.
A few things.
1) What is the purpose of maze2 ? You never use it or change it. Perhaps you should remove maze2 as a parameter and just update/reference maze[][] instead?
2) There is no exit condition. Even when one recursive call reaches the end and returns true, the success message will display and then the program will continue attempting to traverse the maze.
3) There are multiple things wrong with the while loop. For one, the condition will always evaluate as true. It does not look like you break or return out of the loop at all )but you have a few missing braces so I might be wrong).

Categories