# Minesweeper umschreiben



## infinityfan (3. Aug 2011)

Hey leute,
ich habe im Internet nen Quelltext für nen Minesweeper gefunden. Die Sache ist die, jetzt würde ich ihn gerne so anpassen, dass er ohne GUI ist, da ich in dem Bereich noch keine Ahnung habe.
Mein Ziel ist es das ganze in BlueJ über die Konsole zu "spielen". Das Aufdecken der Felder gelingt mir leider noch nicht, hat da jemand eine Idee? Aus der Methode "bewerteFelder" bin ich ehrlichgesagt auch noch nicht wirklich schlau geworden, wofür brauchts die?

Hier mal der Quelltext:

```
import java.util.ArrayList;
import java.util.Random;

public class MinenFeld
{
    private ArrayList felder;
    private int dimX;
    private int dimY;
    private int	minenAnzahl;
    
    public MinenFeld(int dimX, int dimY, int minenAnzahl)
    {
        this.dimX=dimX;
        this.dimY=dimY;
        this.minenAnzahl = minenAnzahl;
        felder = new ArrayList();
        
        erstelleFelder();
        erzeugeMinen();
        bewerteFelder();
    }
    
    private void erstelleFelder()
    {   
        for(int y=0; y<dimY ; y++)
        {
            for(int x=0; x<dimX; x++)
            {
                Feld f = new Feld(x,y);
                felder.add(f);
            }
        }
    }
    
    private void erzeugeMinen()
    {
        int anzahl=dimX*dimY;
        Random rnd = new Random();
        int[] zufall = new int[minenAnzahl];
        boolean doppelt=true;
        
        for(int i=0; i<minenAnzahl; i++)
        {
            while(doppelt == true)
            {
                zufall[i]=rnd.nextInt(anzahl);
                doppelt=false;
                for(int t=0; t<i; t++)
                {
                    if(zufall[t]==zufall[i])
                        doppelt=true;

                }
            }
            doppelt=true;
        }
        
        for(int i=0; i<minenAnzahl; i++)
        {
            ((Feld)felder.get(zufall[i])).setMine(true);
        }          
    }
    
    public Feld getFeld(int index)
    {
        return (Feld)felder.get(index);
    }
    
    private void bewerteFelder()
    {
        for(int i=0; i<felder.size(); i++)
        {
            if(((Feld)felder.get(i)).isMine())
            {
                int x = ((Feld)felder.get(i)).getX();
                int y = ((Feld)felder.get(i)).getY();
               
                if(getIndexOfFeld(x-1,y-1) != -1)
                    ((Feld)felder.get(getIndexOfFeld(x-1,y-1))).erhoeheZaehler(); 
                if(getIndexOfFeld(x,y-1) != -1)
                    ((Feld)felder.get(getIndexOfFeld(x,y-1))).erhoeheZaehler(); 
                if(getIndexOfFeld(x+1,y-1) != -1)
                    ((Feld)felder.get(getIndexOfFeld(x+1,y-1))).erhoeheZaehler(); 
                
                if(getIndexOfFeld(x-1,y) != -1)
                    ((Feld)felder.get(getIndexOfFeld(x-1,y))).erhoeheZaehler(); 
                if(getIndexOfFeld(x+1,y) != -1)
                    ((Feld)felder.get(getIndexOfFeld(x+1,y))).erhoeheZaehler(); 
                
                if(getIndexOfFeld(x-1,y+1) != -1)
                    ((Feld)felder.get(getIndexOfFeld(x-1,y+1))).erhoeheZaehler(); 
                if(getIndexOfFeld(x,y+1) != -1)
                    ((Feld)felder.get(getIndexOfFeld(x,y+1))).erhoeheZaehler(); 
                if(getIndexOfFeld(x+1,y+1) != -1)
                    ((Feld)felder.get(getIndexOfFeld(x+1,y+1))).erhoeheZaehler(); 
            }
        }
    }
    
    public boolean loeseSpiel()
    {
        int anzahl=minenAnzahl;
        
        for(int i=0; i<felder.size(); i++)
        {
            if(((Feld)felder.get(i)).isVorgemerkt()  &&  ((Feld)felder.get(i)).isMine())
                anzahl--;
        }
        
        if(anzahl==0)
            return true;
        return false;
    }
    
    private int getIndexOfFeld(int x, int y)
    {
        int index=-1;
        
        for(int i=0; i<felder.size(); i++)
        {
            if(((Feld)felder.get(i)).getX() == x   &&   
                    ((Feld)felder.get(i)).getY() == y  &&  
                    	!(((Feld)felder.get(i)).isMine()))
            {
                return i;
            }
        }
        return index;
    }
    
    public int getIndexOfFeld2(int x, int y)
    {
        int index=-1;
        
        for(int i=0; i<felder.size(); i++)
        {
            if(((Feld)felder.get(i)).getX() == x   &&   
                    ((Feld)felder.get(i)).getY() == y)
            {
                return i;
            }
        }
        return index;
    }
    
    /**
     * @return Returns the minenAnzahl.
     */
    public int getMinenAnzahl()
    {
        return minenAnzahl;
    }
    /**
     * @return Returns the dimX.
     */
    public int getDimX()
    {
        return dimX;
    }
    /**
     * @return Returns the dimY.
     */
    public int getDimY()
    {
        return dimY;
    }
    
    public int getVorgemerktAnzahl()
    {
        int anzahl=0;
        
        for(int i=0; i<felder.size(); i++)
        {
            if(((Feld)felder.get(i)).isVorgemerkt())
                anzahl++;
        }
        
        return anzahl;
    }
    
    public void zeige()
    {
        String s="";
        
        for(int i=1; i<=(dimX*dimY); i++)
        {
            if(((Feld)felder.get(i-1)).isMine())
                s="0";
            else
                s="0";
            System.out.print(s+" ");
            
            if(i%dimX==0)
                System.out.println();
        }
        
        System.out.println();
        
        for(int i=1; i<=(dimX*dimY); i++)
        {

            s=""+((Feld)felder.get(i-1)).getZaehler();
            System.out.print(s+" ");
            
            if(i%dimX==0)
                System.out.println();
        }
        
        System.out.println();
        
        
    }
    
}
```

Hoffe ihr könnt mir da etwas weiterhelfen, danke schonmal. A ja, wer den Quelltext von "Feld" noch sehen möchte, einfach kurz Bescheid geben.


----------



## c_sidi90 (3. Aug 2011)

Ich würde vorschlagen, du versuchst es selbst zu programmieren, anstatt es nur "umzuschreiben". Dadurch lernst du viel mehr. Es bringt dir nichts etwas zu benutzen, was du selber nicht durchblickst. Um Ideen zu bekommen, wie man vorgeht ist das jedoch nicht verkehrt sich mal Codebeispiele anzuschauen.  So wie ich das verstehe, dient die Methode die du nicht verstehst dazu, zu prüfen ob sich die aufzudeckenden Felder am Rand des Feldes befinden, geprüft wird in alle Richtungen (x,y-1, x-1,y) usw. Dies muss abgefangen werden, damit es keine ArrayOutOfBoundsException gibt. 

Mfg


----------



## Landei (3. Aug 2011)

Ich flechte meinem Vorredner Brei: Schreib es selbst, es ist nicht schwer.

Die Methode ist übrigens zu kompliziert: Bei "Brettspielen" verwendet man üblicherweise eine "unsichtbaren" Rand aus einer Reihe Felder (beim Schach zwei wegen des Springers), die immer "belegt", "blockiert" oder so gelten, oder in deinem Fall null Minen enthalten. Damit braucht man keine Überprüfung mehr.

Wenn du ordentlich objektorientiert programmierst, hast du eine eigene Klasse (ohne jede Ein und Ausgabe) für das zugrundeliegende Modell, und ein Interface für die Bildschirmausgabe. Dann kann eine Klasse das Interface so implementieren, dass alles auf der Konsole ein- und ausgegeben wird, und später (wenn du soweit bist) eine Klasse, die eine ordentliche GUI realisiert. Genauso könntest du es für die Spieler machen (wäre witzig, wenn eine KI _lernen_ würde, Minesweeper zu spielen)


----------



## infinityfan (3. Aug 2011)

Danke euch schonmal für die schnellen Antworten. Naja, Anfangs wollt ich das Teil auch selbst programmieren. Jedoch merkte ich dann schnell dass es etwas zu schwierig ist. Daher habe ich einen bestehenden Code genommen. 
@Landei: Ja das mit der KI wäre schon witzig muss ich sagen, aber da will ich gar nicht erst ans programmieren von dem Ding denken.


----------



## c_sidi90 (3. Aug 2011)

Wieso versuchst du dich nicht erst einmal an etwas wie TicTacToe oder Schiffeversenken? Ich kenne deinen jetzigen Stand in der Programmierung zwar nicht, solltest du jedoch als Anfänger durchgehen, würde ich damit anfangen. Für Spiele wie Minesweeper sollte man schon relativ fit sein, auch was Rekursion angeht. Ich hatte damals auch ein Minesweeper programmiert und erinnere mich, das es 2 Wochen voller Verzweiflung waren, da ich viel zu früh mit dem Thema begonnen habe. 

The easiest way to learn is to start easy


----------

