简体   繁体   中英

How can one get rid of previous iteration of recursive method call?

I have a method that checks if user inputted values are within an arrays bounds:

public static void placeMove(int num1, int num2){
    //checking if x and y are  greater than rows and columns of a 2D array
    if(num1 > rows-1 || num2 > columns-1){
      System.out.println("This space is off the board, try again.");
      int[] values = new int[2];
      values = inputMove(); //calls inputMove method to ask user for new input
      placeMove(values[0],values[1]); //calling itself to check 
                                     //if new values are prohibited
    }
    //code to place a value in grid[num1][num2]
}

I have a 2D array (size of rows and columns vary depending on settings):

char[][] grid = new char[rows][columns];

My placeMove method gives me an ArrayIndexOutOfBoundsException when I error check if num1/num2 are greater than their respective row/col. placeMove invokes a placeMove again and the state of the first call to placeMove are saved in the stack and once execution of the second call to placeMove is completed then the first iteration resumes its further execution with the saved values of its local variables from the Stack and causes the exception. How do I prevent this? Thanks for any help!

Very simple: just return from the function after the recursive call - or place the other code into an else block:

    placeMove(values[0],values[1]);
    return; // <--
}
//code to place a value in grid[num1][num2]

Or:

    placeMove(values[0],values[1]);
}
else
{
    //code to place a value in grid[num1][num2]
}

Actually, though, there is no need for a recursive call, you can have a loop instead:

while(num1 >= rows || num2 >= columns)
// ^ instead of if         ^ (additionally changed comparison)
{
     System.out.println("This space is off the board, try again.");
     int[] values = inputMove();
     //           ^  can assign directly,
     //              (the array you created previously is just GC'ed)
     num1 = values[0];
     num2 = values[1];
}
//code to place a value in grid[num1][num2]

Edit in response to your comment :

I have a call to inputMove() then placeMove(int num1, int num2) and finally a checkWin(int num1, int num2) method respectively in my main method. The checkWin() method uses the values returned from inputMove() method.

Then you should not call inputMove within placeMove , instead:

int main(String[] args)
{
    int[] values = inputMove();
    while(values[0] >= rows || values[1] >= columns)
    // by the way: you do not check for NEGATIVE input!!!
    {
        System.out.println("This space is off the board, try again.");
        values = inputMove();
    }
    placeMove(values[0], values[1]); // <- won't read input any more!
    checkWin(values[0], values[1]);
}

Actually, this rather should have been a new question, prefer to do so next time, preferrably with a reference to the current question...

Edit2 : Actually, checking the input normally is part of getting the input, so my recommendation is moving the while loop into inputMove :

int[] inputMove()
{
    int[] values = new int[2];
    for(;;)
    {
        // read only ROW as before
        if(0 <= values[0] && values[0] < rows)
            break;
        System.out.println("row out of range");
    }
    // now the same for COLUMN
    return values;
}

Main would now just drop the while loop:

int main(String[] args)
{
    int[] values = inputMove();
    placeMove(values[0], values[1]); // <- won't read input any more!
    checkWin(values[0], values[1]);
}

This way, you have clearly grouped together what is most closely related to one and another. Additionally, with the two separate loops for rows and columns, you do not force the user to re-enter the row if the the comlumn only is invalid...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM