Swing Minesweeper Rekursiv

Zeppi

Aktives Mitglied
Moin,
ich versuche gerade die Minen rekursiv aufzudecken. Ich habe ein paar Infos neben den Lines geschrieben, damit die Ausdrücke ein wenig besser zu lesen sind.
[CODE lang="java" title="Rekursionsversuch"]public void revealZero(int x, int y) {
char h;
h = (minen.suche(new Koordinate(x, y))); //hier wird geguckt, was die Nachbarfelder sind
if (x < 0 || x > 11 || y < 0 || y > 15) //hier wird geguckt, ob man innerhalb des Spielfeldes ist
return;

if (h == '0') { //hier wird geguckt, ob man auf eine 0 gestoßen ist

revealZero(x + 1, y); //alle 4 Richtungen werden rekursiv aufgerufen
revealZero(x - 1, y);
revealZero(x, y - 1);
revealZero(x, y + 1);
anzeige.set(x,y,h); //hier wird das Symbol (indem Fall 0) gespeichert und in einer anderen Methode mit anzeige.get(x,y) wiedergegeben
//ich muss irgendwie das anzeige.set(x,y,h) benutzen, sonst hat anzeige.get an der Stelle kein Char
} else {
return;
}[/CODE]

Vielleicht hat jemand ein paar Tipps.
Danke Zeppi
 

fhoffmann

Top Contributor
Bist du dir sicher, dass du nicht Unendlichschleifen einbaust:
revealZero(5, 7) ruft ggf. revealZero(4, 7) auf.
revealZero(4, 7) ruft ggf. revealZero(5, 7) auf.
revealZero(5, 7) ruft ggf. revealZero(4, 7) auf.
revealZero(4, 7) ruft ggf. revealZero(5, 7) auf.
revealZero(5, 7) ruft ggf. revealZero(4, 7) auf.
revealZero(4, 7) ruft ggf. revealZero(5, 7) auf.
revealZero(5, 7) ruft ggf. revealZero(4, 7) auf.
revealZero(4, 7) ruft ggf. revealZero(5, 7) auf.
revealZero(5, 7) ruft ggf. revealZero(4, 7) auf.
revealZero(4, 7) ruft ggf. revealZero(5, 7) auf.
revealZero(5, 7) ruft ggf. revealZero(4, 7) auf.
revealZero(4, 7) ruft ggf. revealZero(5, 7) auf.
revealZero(5, 7) ruft ggf. revealZero(4, 7) auf.
revealZero(4, 7) ruft ggf. revealZero(5, 7) auf.
revealZero(5, 7) ruft ggf. revealZero(4, 7) auf.
revealZero(4, 7) ruft ggf. revealZero(5, 7) auf.
revealZero(5, 7) ruft ggf. revealZero(4, 7) auf.
revealZero(4, 7) ruft ggf. revealZero(5, 7) auf.
...
 

Zeppi

Aktives Mitglied
Bist du dir sicher, dass du nicht Unendlichschleifen einbaust:
revealZero(5, 7) ruft ggf. revealZero(4, 7) auf.
revealZero(4, 7) ruft ggf. revealZero(5, 7) auf.
revealZero(5, 7) ruft ggf. revealZero(4, 7) auf.
revealZero(4, 7) ruft ggf. revealZero(5, 7) auf.
revealZero(5, 7) ruft ggf. revealZero(4, 7) auf.
revealZero(4, 7) ruft ggf. revealZero(5, 7) auf.
revealZero(5, 7) ruft ggf. revealZero(4, 7) auf.
revealZero(4, 7) ruft ggf. revealZero(5, 7) auf.
revealZero(5, 7) ruft ggf. revealZero(4, 7) auf.
revealZero(4, 7) ruft ggf. revealZero(5, 7) auf.
revealZero(5, 7) ruft ggf. revealZero(4, 7) auf.
revealZero(4, 7) ruft ggf. revealZero(5, 7) auf.
revealZero(5, 7) ruft ggf. revealZero(4, 7) auf.
revealZero(4, 7) ruft ggf. revealZero(5, 7) auf.
revealZero(5, 7) ruft ggf. revealZero(4, 7) auf.
revealZero(4, 7) ruft ggf. revealZero(5, 7) auf.
revealZero(5, 7) ruft ggf. revealZero(4, 7) auf.
revealZero(4, 7) ruft ggf. revealZero(5, 7) auf.
...
stimmt, das spuckt er mir als Fehlermeldung auch immer wieder aus. Ich müsste die bereits durchlaufenden Felder so markieren, dass er die nicht nochmal durchläuft. BZW. die Schleife abändern, aber ich wüsste nicht direkt wie.
Hast du einen Tipp?
 

fhoffmann

Top Contributor
minen.suche(new Koordinate(x, y))
Du hast offensichtlich schon eine Klasse Koordinate und ein Objekt minen von einer unbekannten Klasse (Minen ?), die die Methode suche() implementiert.

Wir wissen aber nicht, wie diese Klassen genau aussehen und wie sie zusammenhängen. Es ist auch komisch, dass die Methode revealZero zwei int-Werte und keine Koordinate als Parameter bekommt.
Möglicherweise könnte man sich in Koordinate oder einer anderen Klasse merken, ob das Feld bereits aufgedeckt wurde.

Wenn du uns mehr Code zeigst, können wir dir besser helfen.
 

Zeppi

Aktives Mitglied
[CODE lang="java" title="Koordinate"]public class Koordinate {
private int x;
private int y;

public Koordinate(int X, int Y) {
this.x = X;
this.y = Y;
}[/CODE]
[CODE lang="java" title="Positionen"]public class Positionen {
private Mine[] koor;
private Koordinate koord;


public Positionen(int ANZAHL, int X, int Y) {
koor = new Mine[ANZAHL];
for (int i = 0; i < ANZAHL; i++) {
koor = new Mine(X, Y);
for (int j = 0; j < i; j++) {
if (koor.equals(koor[j])) {
System.out.println("doppelt" + i);
i--;
}
}
}
}


public Mine get(int i) {
return koor;
}


public char suche(Koordinate koord) {
char rueckgabe = '0';
int anzahl = 0;
this.koord = koord;
for (int i = 0; i < koor.length; i++) {
if (koord.equals(koor)) {
return Anzeige.TREFFER;
}
if (koord.istNachbar(koor)) {
anzahl++;
}
}
rueckgabe = (char) ('0' + anzahl);

return rueckgabe;
}
}
[/CODE]
[CODE lang="java" title="JPanel"]@Override
public void mouseClicked(MouseEvent e) {

x = ((e.getX() - offset) / spalteX);
y = ((e.getY() - offset) / spalteY);

if (e.getButton()==MouseEvent.BUTTON1) {
spiel.set(x, y);
if (spiel.get(x, y) == '0') {

spiel.revealZero(x, y);
}

} else {
spiel.markiere(x, y);
}
repaint();

}[/CODE]
[CODE lang="java" title="Spiel"]public class MinesweeperSpiel implements KlickBrettSpiel {
final int X = 12;
final int Y = 16;
final int MINEN = 20;
private char c;
private Positionen minen = new Positionen(MINEN, X, Y);
private Anzeige anzeige = new Anzeige(X, Y);[/CODE]
[CODE lang="java" title="Anzeige"]public class Anzeige {
static final char LEER = ' ';
static final char TREFFER = 'X';
char[][] feld;

public void set(int x, int y, char symbol) {
this.feld[x][y] = symbol;
}
public char get(int x, int y) {
return feld[x][y];
}[/CODE]
 

fhoffmann

Top Contributor
Ich verstehe kein Wort.

- Was ist das für eine Klasse Mine?
- Die Klasse "Positionen" hat zwei Member mit den Namen "koor" und koord" - aus den Namen kann ich nicht folgern, welche Aufgaben die beiden Member haben!

EDIT: Was soll diese Methode (Konstruktor) machen: public Positionen(int ANZAHL, int X, int Y)?
Eine bestimmte Anzahl von Minen an der Position (X, Y) unterbringen?
 
Zuletzt bearbeitet:

Zeppi

Aktives Mitglied
Mine erbt von Koordinate und bekommt als x und y zwei zufällige Werte.
Koord kannst du auch mit einer anderen Variable ersetzen. Mir ist auf die schnelle nicht anderes eingefallen. Koor ist ein Array der Klasse Mine und besitzt einen x und y Wert.
Bei der Methode suche in Positionen wird eine Koordinate (mit x und y Wert) übergeben, diese wird verglichen mit der Koordinate von der Mine (koor), es wird geguckt, ob es ein Treffer war oder wie viele Nachbarfelder mit Minen besetzt sind.
 

fhoffmann

Top Contributor
Mir ist auf die schnelle nicht anderes eingefallen.
Du schreibst den Code einmal und du und andere werden ihn hundertmal lesen. Du solltest dir angewöhnen, dir beim Schreiben des Codes ein bisschen Zeit zu nehmen, sinnvolle Variablennamen zu erfinden, damit bei vielfachen Lesen des Codes nicht tausende Stunden an Arbeit entstehen.
 

Zeppi

Aktives Mitglied
Du schreibst den Code einmal und du und andere werden ihn hundertmal lesen. Du solltest dir angewöhnen, dir beim Schreiben des Codes ein bisschen Zeit zu nehmen, sinnvolle Variablennamen zu erfinden, damit bei vielfachen Lesen des Codes nicht tausende Stunden an Arbeit entstehen.
Vielleicht noch kurz als Anmerkung, die Rekursion findet in der Klasse MinesweeperSpiel statt.
 

fhoffmann

Top Contributor
Ich bin gerade noch dabei, die ganzen Methoden mit JavaDoc-Kommentaren zu erweitern.
Wenn die Methoden und ihre Parameter sprechende Namen haben, kannst du dir die Kommentare sparen.
Mir ist lieber:
Java:
private int breite;
als:
Java:
/**
In x wird die Breite gespeichert.
*/
private int x;

Was nicht bedeuten soll, dass ich grundsätzlich dagegen bin, JavaDoc-Kommentare zu schreiben.
 

Zeppi

Aktives Mitglied
Wenn die Methoden und ihre Parameter sprechende Namen haben, kannst du dir die Kommentare sparen.
Mir ist lieber:
Java:
private int breite;
als:
Java:
/**
In x wird die Breite gespeichert.
*/
private int x;

Was nicht bedeuten soll, dass ich grundsätzlich dagegen bin, JavaDoc-Kommentare zu schreiben.
Für manche Namen kann ich nichts, da die vorgegeben sind aus der Aufgabe.
 

Zeppi

Aktives Mitglied
Ich glaube ich habe die Rekursion hinbekommen, jedenfalls werden sehr viele Nullen auf dem Spielfeld angezeigt, sobald ich getroffen habe.
Für die, die es interessiert, hier einmal meine Lösung:
Java:
public class MinesweeperSpiel implements KlickBrettSpiel {
    final int X = 12; //Spielfeldgröße
    final int Y = 16; //Spielfeldgröße
    final int MINEN = 20; //Anzahl der versteckten Minen
    private char c;  //unwichtig für die Rekursion
    private Positionen minen = new Positionen(MINEN, X, Y);  //hier werden die Minen erzeugt, aber unwichtig für Rekursion
    private Anzeige anzeige = new Anzeige(X, Y);  //für meine Variante wichtig, da man über die Anzeige die Methode set aufruft, und da werden die angeklckten Felder gespeichert
    char benutztesFeld[][] = new char[X][Y];  //ein Array mit dem ich überprüfen kann, ob das Feld schon angeklickt wurde, wichtig für Rekursion
    
        @Override
    public void aufdeckenNull(int x, int y) {  //hier wird eine Koordinate mit einem x und y Wert übergeben
        char hilfsChar; 
        char besetzt = 'B'; 

        hilfsChar = (minen.suche(new Koordinate(x, y))); //ich rufe meine Methode suche auf, dort wird geguckt, was für ein Feld sich an der Position verbirgt, bsp. ein Treffer, Nachbarfeld von Mine oder eine 0

        if (x < 0 || x > 11 || y < 0 || y > 15) { //Ränder des Spielfeldes überprüfen
            return;
        }

        if (benutztesFeld[x][y] == besetzt) {  //überprüfen, ob das Feld schon besetzt ist
            return;
        }
        if (hilfsChar == '0' && benutztesFeld[x][y] != besetzt) {  //wenn das Feld eine 0 ist und vorher nicht besetzt wurde, wird die Rekursion ausgeführt
            benutztesFeld[x][y] = besetzt;  //Array mit mit besetzt markiert
            anzeige.set(x, y, hilfsChar);    //hier wird das Symbol, welches an der Stelle x und y liegt gespeichert
            aufdeckenNull(x + 1, y);
            aufdeckenNull(x - 1, y);
            aufdeckenNull(x, y - 1);
            aufdeckenNull(x, y + 1);
        }
        }
}

sicherlich versteht man nicht alles von meinem Code, aber vielleicht kann jemand es ein wenig umschreiben und für sein Projekt verwenden.
 

Ähnliche Java Themen

Neue Themen


Oben