Hallo,
ich habe es geschafft, einen java.lang.StackOverflowError auszulösen.
Aber erst zur Vorgeschichte:
Ich will mir für ein gewisses Flashspiel ein wenig Code schreiben, der das Spiel für mich spielt.(müsste derzeit ewig grinden und das kann ein Computer einfach besser!)
Zum relevanten Part:
Ich habe so ein Spielfeld mit farbigen Steinen gegeben:
Ziel ist es auf die Gruppe an zusammenhängenden Steinen zu klicken, wo halt die meisten Steine sind (im Beispiel kämen also die grüne oder die blaue Gruppe unten rechts mit 4 Steinen in Frage).
Ich habe mir dieses Spielfeld in vereinfachter Form als 8x8 int Array „feld“ eingelesen, wo jedes Element halt einfahc einen der möglichen Farbwerte 0-5 entspricht (0 steht für „hier ist gar kein Stein“, im Bild nicht vorkommend).
gleichzeitig gibts ein weiteres 8x8 boolean array „unusedfeld“, dessen einträge eingangs auf true gesetzt sind.
Und nun will ich die Steine durchgehen und wenn einstein noch nicht „benutzt“ wurde in einer vorherigen gruppe, mit diesem einzelnen Stein eine neue gruppe bilden
dummyGroup = new Group(i, j, feld[i][j]);
builtGroup(i, j);
und dann davon ausgehend mit der Methode
public void builtGroup(int i, int j) {
if (!(unusedFeld[i][j])) {
return;
}
if (feld[i][j] == dummyGroup.getFarbe()) {
dummyGroup.add();
unusedFeld[i][j] = false;
}
// feld rechts
if (j < width - 1) {
builtGroup(i, j + 1);
}
// feld unten
if (i < height - 1) {
builtGroup(i + 1, j);
}
// feld links
if (j > 0) {
builtGroup(i, j - 1);
}
}
so weit wie möglich in alle Richtungen "die Füler ausstrecken, also der startstein betrachtet sein Nachbarn, diese Nachbarn betrachtne wieder ihre eigenen Nachbarn, etc.
Nur beim Aufruf der builtGroup methode tritt auch gleich der besagte Error auf.
Die naheliegende Vermutung ist dass irgendwie „alte“ Steine wieder aufgesucht werden.
Weil von sich aus kann die Rekursionstiefe eigentlich gar nicht zu tief werden, selbst wenn man im Feld oben links beginnt, könnte im worst case die Rekursionstiefe nur 64 erreichen weil eben nur 64 Felder da sind.
Nichtsdestotrotz tritt der Error auf.
Der Errorlog sieht dann so aus:
Exception in thread "main" java.lang.StackOverflowError
at a.Feld.builtGroup(Feld.java:98)
at a.Feld.builtGroup(Feld.java:90)
at a.Feld.builtGroup(Feld.java:98)
at a.Feld.builtGroup(Feld.java:90)
at a.Feld.builtGroup(Feld.java:98)
at a.Feld.builtGroup(Feld.java:90)
at a.Feld.builtGroup(Feld.java:98)
......
at a.Feld.builtGroup(Feld.java:90)
at a.Feld.builtGroup(Feld.java:98)
at a.Feld.builtGroup(Feld.java:90)
at a.Feld.builtGroup(Feld.java:98)
at a.Feld.builtGroup(Feld.java:90)
wobei ich da hunderte ähnliche Zeilen nicht mit abgedruckt habe.
Ich sehe aktuell leider nicht wirklich wo der Fehler liegt.
Eigentlich wird ja ein Feld, sobald besucht. gleich als benutzt markiert.
Warum es dann doch wieder benutzt wird, ist mir ein Rätsel :-/
Kann mir da Jemand weiterhelfen?
Falls ich den ganzen Algorithmus irgendwie ohne Rekursion machen könnte, wäre mir das natürlich noch lieber!