2017-07-14 3 views
0

Ich habe eine Methode, die Benutzer eingegebene Werte innerhalb einer Array-Grenzen überprüft, ob:Wie kann man die vorherige Iteration des rekursiven Methodenaufrufs loswerden?

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 einen 2D-Array (Größe der Zeilen und Spalten variieren, je nach Einstellung):

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

My Die Methode placeMove gibt mir eine ArrayIndexOutOfBoundsException, wenn ich einen Fehler überprüfe, ob num1/num2 größer als ihre jeweilige Zeile/Spalte ist. placeMove ruft einen placeMove erneut auf und der Zustand des ersten Aufrufs von placeMove wird im Stack gespeichert und sobald die Ausführung des zweiten Aufrufs von placeMove abgeschlossen ist, nimmt die erste Iteration ihre weitere Ausführung mit den gespeicherten Werten ihrer lokalen Variablen aus dem Stack und wieder auf verursacht die Ausnahme. Wie verhindere ich das? Danke für jede Hilfe!

+0

@JBNizet Ich weiß, warum der Fehler passiert, versuche ich einen Benutzer behandeln, der eine Bewegung außerhalb des Rasters eingeben kann, indem er sie auffordert, eine neue Bewegung einzugeben, aber sobald sie ihre neue Bewegung hinzugefügt hat, wird der vorherige Aufruf der Funktion mit ihrer Off-Grid-Bewegung ausgeführt und verursacht die Ausnahme. – splash

Antwort

1

Sehr einfach: return aus der Funktion nach dem rekursive Aufruf - oder setzen Sie den anderen Code in einen anderen Block:

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

Oder:

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

Eigentlich gibt aber keine müssen für einen rekursiven Aufruf, können Sie eine Schleife haben statt:

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] 

bearbeiten als Antwort auf Ihren Kommentar:

Ich habe einen Anruf zu inputMove() dann placeMove (int num1, int num2) und schließlich ein checkWin (int num1, int num2) -Methode jeweils in meinem Haupt-Methode. Die Methode checkWin() verwendet die von der Methode inputMove() zurückgegebenen Werte.

Dann sollten Sie nicht Anruf inputMoveinnerhalbplaceMove statt:

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]); 
} 

Eigentlich ist dies eher sollte eine neue Frage gewesen, lieber so beim nächsten Mal zu tun, vorzugsweise mit einer Referenz zur aktuellen Frage ...

Edit2: Eigentlich ist das Überprüfen der Eingabe normalerweise Teil des Erhaltens Eingang, so meine Empfehlung bewegt die while-Schleife in 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; 
} 

Haupt würde jetzt nur noch die while-Schleife fallen:

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

Auf diese Weise haben Sie klar zusammengefasst, was am ehesten ist verwandt mit der eine und der andere. Darüber hinaus zwingen Sie mit den zwei separaten Schleifen für Zeilen und Spalten den Benutzer nicht, die Zeile erneut einzugeben, wenn die Spalte nur ungültig ist ...

+0

Das ist wirklich hilfreich, ich habe es ausprobiert und mir ist klar, dass ich eine andere Methode verwende, die die Werte der inputMove() -Methode verwendet, die prüft, ob der Benutzer gewonnen hat. Also brauche ich die geänderten Werte von der Methode placeMove, um mit dem Programm fortzufahren. Mein Programm ist wirklich überall. – splash

+0

@splash Wollen Sie die neuesten Eingaben erneut verwenden, ohne dass der Benutzer neue Werte angibt? Wenn ja, müssen Sie die letzte Eingabe irgendwo zwischenspeichern ... – Aconcagua

+0

Ja genau, ich habe einen Aufruf von inputMove() dann placeMove (int num1, int num2) und schließlich eine Methode checkWin (int num1, int num2) in meinem Hauptmethode. Die Methode checkWin() verwendet die von der Methode inputMove() zurückgegebenen Werte. Ich kann nicht herausfinden, wie die neuen Werte von placeMove an checkWin gesendet werden. – splash

Verwandte Themen