Problem Mit Miensweeper Clone & rekursive Methode

Hi,

ich schreib gerade just 4 fun einen Mienesweeper Clone und an der Spannsten Stelle eigendlich, beiß ich mir die zähne aus.

Und zwar bei der Methode wie ich bei Click auf ein Leeres Feld dann das ganze sich weiter "aufklickt" wen die Felder Leer sind bis zu einer zahl.

Nach vielem Gegoogle && auch nach Durchsuchen des Boards bin ich darauf gestoßen das gnaze mit einer rekursive Methode zu lösen hier bekomme ich aber ein Stack OverFlow. Und finde nicht heraus warum.

Hier mal mein Code:

Java:
package minesweeper.logic;

import minesweeper.api.Field;


public class CanOpenNextField {

    public void open(int x, int y, Field[][] gameBoard) {
        // prüfen ob rekursion beendet werden muss
        if (gameBoard[x][y].isBoombe() == true
                || gameBoard[x][y].isMarked() == true
                || isValidField(x, y, gameBoard) == false) {
            System.out.println("Abbruch");
            return;
        }


        // feld aufdecken
        gameBoard[x][y].setIsOpen(true);
        System.out.println("Ich bin X : " + x);
        System.out.println("Ich bin y : " + y);
        System.out.println("Is Vaild Field :" + isValidField(x, y, gameBoard));
        // in alle 4 Richtungen weitermachen
        open(x - 1, y, gameBoard);
        open(x + 1, y, gameBoard);
        open(x, y + 1, gameBoard);
        open(x, y - 1, gameBoard);
    }

    public boolean isValidField(int x, int y, Field[][] gameBoard) {
        if (x <= 0 || y >= gameBoard.length -1) {
            System.out.println();
            return false;
        }

        return true;

    }
}

Die Ausgabe der des Ganzen beim Debuggen sied dan so aus

Java:
Ich bin X : 4
Ich bin y : 4
Is Vaild Field :true
Ich bin X : 3
Ich bin y : 4
Is Vaild Field :true
Ich bin X : 2
Ich bin y : 4
Is Vaild Field :true
Ich bin X : 1
Ich bin y : 4
Is Vaild Field :true

Abbruch
Ich bin X : 2
Ich bin y : 4
Is Vaild Field :true
Ich bin X : 1
Ich bin y : 4
Is Vaild Field :true

Abbruch
Ich bin X : 2
Ich bin y : 4
Is Vaild Field :true
Ich bin X : 1
Ich bin y : 4
Is Vaild Field :true

Also bricht er leider nicht ab.

Hab ihr eine Idee was ich falsch mache ?
Grüße und Thx
 
zunächst Reihenfolge, isValidField(x, y, gameBoard) solltest du VOR irgendeinem Zugriff gameBoard[x][y] machen,
sonst gibt es nämlich bei x == -1 einen Fehler, bevor du valid prüfst,
speichere außerdem gameBoard[x][y] in einer Variablen, schreibe das nicht mehrfach

überlege auch stark, gameboard zu einem Instanz oder notfallst statischen Attribut zu machen, nicht bei jeder Methode übergeben..

du musst dir irgendeinen Abbruch überlegen, soll isMarked() die Suche begrenzen? dann fehlt wahrscheinlich ein Aufruf a la setMarked()?!
falls Marked für was anderes gut ist, könntes du ein zweites ähnliches Attribut einfügen

neu strukturierter Ablauf:
Java:
public void open(int x, int y) {
    // Prüfung Valid 
    // Ausgabe x + y + valid, evtl Abbruch
	
	Field f = gameBoard[x][y]; 
	// jetzt nur noch f verwenden, nicht gameBoard[x][y] ständig schreiben 
	
	// Ausgabe ob f für Suche bereits markiert ist, ob es Bombe ist und was immer interessant ist,

	// falls markiert, falls Bombe usw. dann gegebenenfalls Aktion + Abbruch, 
	// übrigens: if (x || y ||!z) statt if (x == true || y == true || z == false)
	
    // f markieren, sollte nie wieder für diese Rekursion in Ausgabe ohne Markierung erscheinen,
	// nicht vergessen vor nächster Suche Markierung zu löschen, wobei pro Feld in einem Spiel
	// vielleicht nur einmal Suche nötig
	
	// Rekursionsaufrufe mit +-1 wie du sie hast, besser ohne gameBoard-Parameter
}
 
Als ich einen MineSweeper-Klon geschrieben habe, hatte ich dieses automatische Aufdecken auch erst als rekursiven Aufruf. Bei einem 30x24-Feld mit 10 Minen und -Xss128k hat er sich auch mit einem StackOverflowError verabschiedet. Erst mit -Xss256k ging es. Bin dann auf einen iterativen Ansatz umgestiegen und würd ihn dir auch empfehlen.
 
hi @ all

erstmal Danke für die schnellen antworten.

@Marco, genau das war es manchmal vor lauter wald die Bäume nicht.

Java:
gameBoard[x][y].IsOpen() == true

Also somit gelöst das ganze.

@SlaterB ich werde mir deinen rat zu herzen nehmen und den ganzen ablauf nochmal überdenken, danke hier für deine mühen.

Grüße
 

Zurück
Oben