Springerproblem schmeißt Exception

xyZman

Bekanntes Mitglied
Hi Forum.
Gegeben ist z.b ein Feld 5x5 und die Startposition meines Springers.
Das Problem ist nun das jedes Feld nur einmal besucht werden darf.

Ich habe das ganze nun rekursiv umgesetzt.
Doch schmeißt er mit in Zeile 29,123 ein Array Out of bounds(egal welche Feldgröße und Position)
Ich wäre sehr dankbar über jede Hilfe : )

Java:
/******************************  Springer.java  *******************************/

import AlgoTools.IO;
/**
XyZman
*/
public class Springer {

   /**
    * Loest das Springer-Problem, indem alle Zugmoeglichkeiten
    * durchgegangen werden und nach Setzen des Springers die Methode
    * rekursiv mit der naechsten Zugnummer und der neuen Position
    * wieder aufgerufen wird.
    *
    * @param a
    * @param n
    * @param zeile
    * @param spalte
    *
    * @return true, falls Springer-Problem loesbar
    */
  private static boolean springe(int[][]a, int n, int zeile, int spalte){

    //Loesung gefunden, wenn Zugnummer groesser als Anzahl der Felder
    if (!(n<=a.length*a.length)){
        return true;
    }
    //rekursiv die acht Zugmoeglichkeiten durchspielen
  [B] if (a[zeile+1][spalte+2]==0 && zeile+1<=a.length-1 &&
        zeile+1>=0 && spalte+2<=a.length-1 && spalte+2>=0)[/B]{
        springe(a, n++, zeile+1, spalte+2);
        a[zeile+1][spalte+2] = n;
    }
    else if (a[zeile+2][spalte+1]==0 && zeile+2<=a.length-1 &&
             zeile+2>=0 && spalte+1<=a.length-1 && spalte+1>=0){
             springe(a, n++, zeile+2, spalte+1);
             a[zeile+2][spalte+1] = n;
    }
    else if (a[zeile+2][spalte-1]==0 && zeile+2<=a.length-1 &&
             zeile+2>=0 && spalte-1<=a.length-1 && spalte-1>=0){
             springe(a, n++, zeile+2, spalte-1);
             a[zeile+2][spalte-1] = n;
    }
    else if (a[zeile+1][spalte-2]==0 && zeile+1<=a.length-1 &&
             zeile+1>=0 && spalte-2<=a.length-1 && spalte-2>=0){
             springe(a, n++, zeile+1, spalte-2);
            a[zeile+1][spalte-2] = n;
    }
    else if (a[zeile-1][spalte-2]==0 && zeile-1<=a.length-1 &&
             zeile-1>=0 && spalte-2<=a.length-1 && spalte-2>=0){
             springe(a, n++, zeile-1, spalte-2);
             a[zeile-1][spalte-2] = n;
    }
    else if (a[zeile-2][spalte-1]==0 && zeile-2<=a.length-1 &&
             zeile-2>=0 && spalte-1<=a.length-1 && spalte-1>=0){
             springe(a, n++, zeile-2, spalte-1);
             a[zeile-2][spalte-1] = n;
    }
    else if (a[zeile-2][spalte+1]==0 && zeile-2<=a.length-1 &&
             zeile-2>=0 && spalte+1<=a.length-1 && spalte+1>=0){
             springe(a, n++, zeile-2, spalte+1);
             a[zeile-2][spalte+1] = n;
    }
    else if (a[zeile-1][spalte+2]==0 && zeile-1<=a.length-1 &&
             zeile-1>=0 && spalte+2<=a.length-1 && spalte+2>=0){
             springe(a, n++, zeile-1, spalte+2);
             a[zeile-1][spalte+2] = n;
    }

    return false;
  }
  private static void druckeSchachSpiel(int[][]a){

    for (int j=0; j<a.length; j++){
        IO.print("+");
        IO.print("-");
    }
    IO.println("+");
    for (int i=0; i<a.length; i++){
        for (int j=0; j<a[i].length; j++){
            IO.print("|");
            IO.print(a[i][j]);
        }
        IO.print("|");
        for (int j=0; j<a[i].length; j++){
            IO.print("+");
            IO.print("-");
        }
        IO.print("+");
    }

  }

  public static void main(String[] argv) {

    //Feldgroesse z einlesen
    int z;
    do{
        z = IO.readInt("Feldergroesse(>=5):");
    } while(z<5);

    //Schach-Spiel der Groesse zxz
    int[][]a = new int[z][z];

    //Startposition des Springers festlegen
    int zeile, spalte;
    IO.print("Startposition des Springers");
    IO.println();

    do{
        zeile = IO.readInt("Zeile(zwischen 0 und "+(z-1)+"):");
    } while(zeile>z-1 || zeile<0);

    do{
        spalte = IO.readInt("Spalte(zwischen 0 und "+(z-1)+"):");
    } while(spalte>z-1 || spalte<0);

    //Zugnummer
    int n = 1;
    a[zeile][spalte] = n;

    //Wahrheitswert aus springe zeigt, ob loesbar
   [B] if (springe(a, n, zeile, spalte)==true)[/B]{
        IO.print("Springer-Problem ist loesbar");
        druckeSchachSpiel(a);
    }
  }
}
 
Zuletzt bearbeitet:
G

Gast2

Gast
Java:
a[zeile+1][spalte+2]
Mit welchen Werten rufst du die Methode auf?
Bist du sicher dass zeile und spalte nie zu groß werden?
 

xyZman

Bekanntes Mitglied
Nein natürlich bin ich mir nicht sicher, sonst würd er ja kein Exception schmeißen???:L
Ich weis nur nich wie ich die Werte sonst festelgen soll:bahnhof:
 
Zuletzt bearbeitet:

werkuh

Mitglied
falls es dir weiterhilft... die out-of-bound exception entsteht hier:

Java:
if ([B]a[zeile+1][spalte+2]==0[/B] && zeile+1<=a.length-1 &&
        zeile+1>=0 && spalte+2<=a.length-1 && spalte+2>=0)[/B]{
        springe(a, n++, zeile+1, spalte+2);
        a[zeile+1][spalte+2] = n;
    }

an der fett markierten stelle greifst du im dritten durchlauf (zeile = 2, spalte = 4) auf die stelle spalte = 6 zu, die logischerweise nicht existiert (gestestet mit 5*5-feld)

edit: fett marken im code geht anscheinend nicht ^^ stell es dir einfach markiert vor :) die tags sind ja da ^^
 
Zuletzt bearbeitet:

StupidAttack

Bekanntes Mitglied
Ohne jetzt deinen ganzen Code angeschaut zu haben:

Ich habe mal ein Connect Four mit Alpha Peta Pruning implementiert und hatte auch mit dem Problem zu kämpfen gültige Züge zu überprüfen, da der Algo aus dem Spielfeld gehüpft ist. Wahrscheinlich rufst du springe() in einer For Schleife auf auf jeder Position im 8*8 Feld. Sobald es aber eine Randposition ist, beschert dir beispielsweise eine folgende CodeZeile eine Exception:
a[zeile+1][spalte+2]

Wir können dir vermutlich nicht helfen. Was ich dir allerdings raten kann: Vergiss Additionen/Subraktionen innerhalb des Indizes (also array[hier][und hier]). Das ist unklug. Dein Programm muss vielmehr wissen, in welcher Position ein Springerzug in eine bestimmte Richtung sinnvoll sein kann und es darf nicht einfach alle in bester Brute-Force Manier durchprobieren.

Oder aber: Du vergrössert dein Spielfeld auf grösse 10*10, dann kan der Algo keine Exceptions mehr werfen. Folge: Immenser Geschwindigkeitsverliust, funktioniert aber...

Ein mit schleichendem Verdacht behaftetem Anfänger, dass ich das Thema vollkommen verfehlte, wünscht dir viel Glück.
 

Ark

Top Contributor
Wegen der vielen if-elses: Extrahiere alle Deltas, die den Übergang des Springers von einem Feld zu einem nächsten beschreiben, und speichere sie in einem Array. So brauchst du nur noch eine Schleife.
Java:
private static final int[][] DELTA=new int[][]{
	{-2,-1}, {-2, 1}, { 2,-1}, { 2, 1},
	{-1,-2}, {-1, 2}, { 1,-2}, { 1, 2}
};
Ark
 

werkuh

Mitglied
naja ich bastel ja grad an der gleichen aufgabe rum (ist von der uni), es wurde zwar nicht explizit gesagt, dass wir keine heuristiken benutzen dürfen, aber kennen tun wir sie auch noch nicht, also denke ich mal, wir sollen das mittels brute-force lösen.. war bei der letzten aufgabe mit backtracking auch so (da gings um sudoku)..
 

GulliOS

Neues Mitglied
Hi,

ich bin ein Kommilitone von dir. Mein Programm läuft soweit. Kannst du mir sagen, wie ich Programmcode aus der Puttyconsole in den Windowszwischenspeicher kopieren kann, damit ich hier meinen Code posten kann?

Bei mir habe ich die Zugmöglichkeiten wie Ark geschrieben hat, in ein extra Array reingepackt und dann mit einer Schleife gearbeitet.

Das n habe ich vor dem rekursiven Aufruf erhöht (erst hatte ich es auch im Aufruf drin, was nicht funktioniert hat)

Den rekursiven Aufruf habe ich wie bei der Musterlösung des Sudokuprogramms gestaltet:

[Java] if (gueltigeZahl(sudoku, number, spalte, zeile)) {
sudoku[zeile][spalte] = number;
if (!fuelleFeld(sudoku, spalte, zeile)) {
sudoku[zeile][spalte] = 0; [/Java]

also als if-Bedinung die, falls es keine Lösung gab, die Stelle im Array die du zuvor auf n gesetzt hast wieder auf 0 setzt und außerdem das n was zuvor erhöht wurde, wieder um 1 erniedrigt.

Hoffe ich konnte dir helfen, sonst melde dich nochmal und ich lass dir irgendwie meinen Code zukommen.

Gruß

PS: Ich habe keine Ahnung wie ich die Elfen Aufgabe lösen soll. Hast du dafür vllt. schon eine Lösung?
 

Oben