# Minesweeper Klon



## stulleman (31. Jul 2011)

Hallo zusammen!
Mit ist leider kein besserer Name eingefallen 
Ich schreibe zurzeit einen kleinen Klon vom MS Minesweeper und ich stehe jetzt vor einem kleinen Problem.
Ich hoffe der eine oder andere kennt/kann das Spiel und weiß das wenn man auf ein Feld klickt, dass keine Mine drumherum hat, das dann alle Felder aufgedeckt werden die ebenfalls drumherum keine Minen im Umfeld haben.
Diese Funktion würde ich auch gerne einbauen aber ich weiß nicht wie.
Mein erster Ansatz war das ich bei jedem Button der gedrückt wurde und als value 0 hatte (also keine Mine im Umfeld) dieser dann eine Methode aufgerufen hat die alle Buttons um x,y aufdeckt. Wie man sich vorstellen kann ist das ja dann sehr verschachtelt und ich habe eine Exception bekommen.
Vielleicht hat einer eine Idee wie man das sauber lösen kann?

Max


----------



## Gast2 (31. Jul 2011)

Ich würd mir dafür ne rekursive Methode schreiben die ausgehend von nem bestimmten Feld in alle 4 Richtungen expandiert.

EDIT:
ganz simpel vllt sowas in der art:

```
public void expand(int x, int y) {
  // prüfen ob rekursion beendet werden muss
  if (isFieldOpen(x,y) || !isValidField(x,y) || isMine(x,y)) {
    return;
  }
  
  // feld aufdecken
  showField(x,y);

  // in alle 4 Richtungen weitermachen
  expand(x-1,y);
  expand(x+1,y);
  expand(x,y+1);
  expand(x,y-1);
}
```


----------



## stulleman (31. Jul 2011)

```
@Override
			public void mouseClicked(MouseEvent e) {
				isClicked = true;
				setBackground(Color.lightGray);
				
				if(model.getMinesAround(x, y) == 0) {
					gamePanel.expand(x, y);
				}
				
				if(model.getField(x, y) != 1) {
					minesAround = model.getMinesAround(x, y);
				} else {
					//TODO: Handle mine!
				}
				
				showValue();
			}
```

Das passiert wenn auf einen Button gedrückt wird.
Und so habe ich es implementiert:


```
public void expand(int x, int y) {
		  if(model.getMinesAround(x, y) != 0 || model.getField(x, y) == -1) {
			  return;
		  }
		  
		  // feld aufdecken
		  fields[x][y].showField();
		 
		  // in alle 4 Richtungen weitermachen
		  expand(x-1,y);
		  expand(x+1,y);
		  expand(x,y+1);
		  expand(x,y-1);
	}
```

Kriege jedes mal einen Stackoverflow error und nur eine Linie nach Links deckt sich auf!


----------



## Gast2 (31. Jul 2011)

dann greift deine abbruchbedingung nicht.


----------



## stulleman (31. Jul 2011)

Aber mir fällt nicht ein was ich ändern soll?


```
Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError
	at java.awt.Component.firePropertyChange(Unknown Source)
	at java.awt.Component.setBackground(Unknown Source)
	at javax.swing.JComponent.setBackground(Unknown Source)
	at de.pk.maximilian.games.MinesweeperField.showField(MinesweeperField.java:100)
	at de.pk.maximilian.games.GamePanel.expand(GamePanel.java:44)
	at de.pk.maximilian.games.GamePanel.expand(GamePanel.java:48)
	at de.pk.maximilian.games.GamePanel.expand(GamePanel.java:47)
	at de.pk.maximilian.games.GamePanel.expand(GamePanel.java:48)
	at de.pk.maximilian.games.GamePanel.expand(GamePanel.java:47)
	at de.pk.maximilian.games.GamePanel.expand(GamePanel.java:48)
	at de.pk.maximilian.games.GamePanel.expand(GamePanel.java:47)
	at de.pk.maximilian.games.GamePanel.expand(GamePanel.java:48)
```

die ist eigentlich noch ein bisschen länger...


```
if(model.getMinesAround(x, y) != 0 || model.getField(x, y) == -1 || model.getField(x, y) == 1) {
			  return;
		  }
```

Das ist jetzt die Abbruchbedingung...
Hast du vielleicht ne Idee was daran falsch sein kann?

EDIT: getField(x,y) gibt -1 zurück wenn es das Feld nicht gibt, 1 wenn es eine Mine ist und 0 wenn keine Mine drauf ist.


----------



## Gast2 (31. Jul 2011)

Lass dir model.getMinesAround(x, y) und model.getField(x, y) mal ausgeben.
Die liefern offenbar nicht die richtigen werte zurück


----------



## stulleman (31. Jul 2011)

Es ist ziemlich schwer nachzuvollziehen ob die Werte richtig sind.
Die Werte könnten richtig sein die mir ausgegeben werden, nachprüfen kann ich das nicht. Zumal mir ca 50 Werte ausgegeben werden wenn ich nur getMinesAround(x,y) ausgeben lasse.
Ich denke ich bin das Problem falsch angegangen und Programmiere zu Kreuz und Quer...
Vielleicht fällt dir ja noch was ein, wenn nicht danke erst mal für die Mühe!


----------



## Gast2 (31. Jul 2011)

Du kannst dir doch ganz einfach sowas ausgeben lassen:
"Bin im moment am Feld {x,y}"
"minesAround: {z}"
"fieldType: {t}"
Daran kannst du doch erkennen ob die werte korrekt sind oder nicht.


----------



## stulleman (1. Aug 2011)

Sooo nach sehr viel Arbeit habe ich es jetzt endlich geschafft das es einigermaßen funktioniert!
Das Problem was weiterhin besteht ist das jetzt zwar alle Felder aufgedeckt werden die leer sind, doch in der Version von MS werden jetzt noch die Felder angezeigt die wieder Mienen im Umkreis haben.
Vielleicht hat dazu jemand eine Idee? Bin gerade echt Ratlos!


----------



## Gast2 (1. Aug 2011)

Du sagst ihm ja auch dass der die Rekursion abbrechen soll wenn

```
model.getMinesAround(x, y) != 0
```
ist, und das bedeutet ja dass er sobald er auf deine Zahl trifft diese Feld nicht aufdeckt und die Rekursion beendet.

Du müsstest also so vorgehen:
- prüfen ob feld gültig && keine mine
- feld aufdecken
- wenn getMinesAround == 0 dann rekursion in alle richtungen fortsetzen


----------



## stulleman (1. Aug 2011)

Super danke! Klappt super!


----------

