Minesweeper - Daten

alapychak07

Mitglied
Hallo,

ich möchte eine Klasse Spielfeld erstellen,in der ein zweidimensionales Array von Objekten der Klasse Feld referenziert wird.Die Größe des Spielfeldes und die Anzahl der Minen sollen dabei im Konstruktor als Parameter angegeben werden können. Der Konstruktor verteilt dann die Minen zufällig im Spielfeld und definiert bei den Nachbarfeldern die Anzahl der angrenzenden Minen.
Nun stellt sich mir eine grobe Frage.

Wie erstelle ich dies?
 
Java:
class Feld{
 
    boolean istMine;
    boolean offen;
    int anzahl;

    public void Feld(){
        offen = false;
        istMine = false;
        anzahl = 0;
    }
    public boolean getMine(){
        return istMine;
    }
    public void setMine(){
        istMine=true;
    }
    public void setNachbar(){
        anzahl++;
    }
    public printFeld(){
        if(istMine==true){
            return("X");
    
        }
        else{
            return String(anzahl);
        }
    }

class Spielfeld{
    
        int hohe;
        int breite;
        int anzahlMine;
    
  Spielfeld(int h, int b, int a){
            hohe= h;
            breite = b;
            anzahl = a;
              Feld[][] bombs= new Feld[breite][hohe];
for(int i=0;i<hohe;i++){
                for(int j=0; j<breite;j++){
                    bombs[i][j] = new Feld();
                }
            }


}
 
1. Ich geh stark davon aus, dass das Array nicht nur lokal im Konstruktor existieren soll
2. Wenn du nun zufällig x Minen haben möchtest musst du beim erstellen per Zufall schauen, ob eine Bedingung erfüllt ist (zB. ob ein boolean true ist und ob du noch Minen belegen darfst)
Den zufälligen boolschen Wert bekommst du so
Java:
Random rand = new Random();
rand.nextBoolean();
Immer wenn du eine Mine setzt musst du einen Counter hochzählen und ein Feld darf nur dann zu einer Mine werden, wenn sowohl der Boolean true ist also auch counter < MAX_AMOUNT_OF_MINES true ist
 
Java:
class Spielfeld{
public static void main(String[] args) { 
        int m = Integer.parseInt(args[0]);
        int n = Integer.parseInt(args[1]);
        double p = Double.parseDouble(args[2]);
     
        boolean[][] bombs = new boolean[m+2][n+2];
        for (int i = 1; i <= m; i++)
            for (int j = 1; j <= n; j++)
                bombs[i][j] = (Math.random() < p);

        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++)
                if (bombs[i][j]) System.out.print("* ");
                else             System.out.print(". ");
            System.out.println();
        }

        int[][] sol = new int[m+2][n+2];
        for (int i = 1; i <= m; i++)
            for (int j = 1; j <= n; j++)
                for (int ii = i - 1; ii <= i + 1; ii++)
                    for (int jj = j - 1; jj <= j + 1; jj++)
                        if (bombs[ii][jj]) sol[i][j]++;
        System.out.println();
        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
                if (bombs[i][j]) System.out.print("* ");
                else             System.out.print(sol[i][j] + " ");
            }
            System.out.println();
        }

    }
}
Soll es so sein?
 
Was machst du da? Das hat doch nichts mit dem zu tun, was ich oben beschrieben hatte. Wozu das 2D boolean Array?
Das hier reicht völlig aus:
Java:
  public Spielfeld(int width, int height, int bombsAmount) {
    this.bombs = new Feld[width][height];
  
    final Random rand = new Random();
    int bombsCounter = 0;
  
    for(int i = 0; i < bombs.length; i++) {
      for(int j = 0; j < bombs[i].length; j++) {
        bombs[i][j] = new Feld();
        if(rand.nextBoolean() && bombsCounter < bombsAmount) {
           bombsCounter++;
           bombs[i][j].setMine(true);
        }
      }
    }
  }
 
Was machst du da? Das hat doch nichts mit dem zu tun, was ich oben beschrieben hatte. Wozu das 2D boolean Array?
Das hier reicht völlig aus:
Java:
  public Spielfeld(int width, int height, int bombsAmount) {
    this.bombs = new Feld[width][height];
 
    final Random rand = new Random();
    int bombsCounter = 0;
 
    for(int i = 0; i < bombs.length; i++) {
      for(int j = 0; j < bombs[i].length; j++) {
        bombs[i][j] = new Feld();
        if(rand.nextBoolean() && bombsCounter < bombsAmount) {
           bombsCounter++;
           bombs[i][j].setMine(true);
        }
      }
    }
  }

das funktioniert nicht zusammen
Java:
public class Feld{ 
    boolean istMine;
    boolean offen;
    int anzahl;
    public void Feld(){
        offen = false;
        istMine = false;
        anzahl = 0;
        }
    public boolean getMine(){
        return istMine;
    }
    public void setMine(){
        istMine=true;
    }
    public void setNachbar(){
        anzahl++;
    }
    public String printFeld(){
        if(istMine==true){
            return("X");
     
        }
        else{
            return Integer.toString(anzahl);
        }
    }
 

}
 public  Spielfeld(int width, int height, int bombsAmount) {
    this.bombs = new Feld[width][height];
 
    final Random rand = new Random();
    int bombsCounter = 0;
 
    for(int i = 0; i < bombs.length; i++) {
      for(int j = 0; j < bombs[i].length; j++) {
        bombs[i][j] = new Feld();
        if(rand.nextBoolean() && bombsCounter < bombsAmount) {
           bombsCounter++;
           bombs[i][j].setMine(true);
        }
      }
    }
  }
  }
[/QUOTE]
 
Du hast es auch in die falsche Klasse gepackt. Das ist der Konstruktor für die Klasse Spielfeld. Du versuchst gerade den Konstruktor in der Klasse Feld zu überschreiben.
Hast du das ganze Thema Klassen / Konstruktoren - bzw die Java Grundlagen an sich - denn schon verinnerlicht? Vielleicht solltest du noch mal einen Schritt zurück gehen und dir die Grundlagen noch mal anschauen.

Edit: Genauer gesagt, steht der Konstruktor nicht mal in der Klasse Feld. Du definierst den Konstruktor gerade außerhalb einer Klasse
 
Ich bin Anfänger, deshalb verstehe ich nicht immer was du meinst(
Du hast es auch in die falsche Klasse gepackt. Das ist der Konstruktor für die Klasse Spielfeld. Du versuchst gerade den Konstruktor in der Klasse Feld zu überschreiben.
Hast du das ganze Thema Klassen / Konstruktoren - bzw die Java Grundlagen an sich - denn schon verinnerlicht? Vielleicht solltest du noch mal einen Schritt zurück gehen und dir die Grundlagen noch mal anschauen.

Edit: Genauer gesagt, steht der Konstruktor nicht mal in der Klasse Feld. Du definierst den Konstruktor gerade außerhalb einer Klasse
;
 
Was genau verstehst du denn nicht. Und Anfänger sein ist das eine. Aber du merkst ja selber, dass es an den Grundlagen irgendwo hapert .. Also Buch nehmen und nachlesen oder hier nachfragen 😉
 
Die Frage verstehe ich nich ganz.
Du hattest doch vorhin schon einen recht soliden Anfang.
Die Klasse Feld beschreibt ein einziges (Minen-) Feld.
Die Klasse Spielfeld besitzt ein Array von Feld-Objekte. Deine Aufgabe sollte es nun sein im Konstruktor der Spielfeld-Klasse das Array zu initialisieren und zufällig x Minen festzulegen.
Das Initialisieren hattest du ja schon ganz gut gemeistert. Erstellt eine verschachtelte for-Schleife um durch das Array zu laufen und jedes Element zu initialisieren. Jetzt brauchst du noch einen Weg um ein Feld zufällig als Mine festzulegen. Das hate ich oben schon beschrieben. Nimm dazu zB die Random Klasse und lass dir für jedes Feld zufällig einen boolean generieren. Wenn dieser boolean true ist und du noch nicht alle Minen festgelegt hast hast du eine neue Mine
 
Die Frage verstehe ich nich ganz.
Du hattest doch vorhin schon einen recht soliden Anfang.
Die Klasse Feld beschreibt ein einziges (Minen-) Feld.
Die Klasse Spielfeld besitzt ein Array von Feld-Objekte. Deine Aufgabe sollte es nun sein im Konstruktor der Spielfeld-Klasse das Array zu initialisieren und zufällig x Minen festzulegen.
Das Initialisieren hattest du ja schon ganz gut gemeistert. Erstellt eine verschachtelte for-Schleife um durch das Array zu laufen und jedes Element zu initialisieren. Jetzt brauchst du noch einen Weg um ein Feld zufällig als Mine festzulegen. Das hate ich oben schon beschrieben. Nimm dazu zB die Random Klasse und lass dir für jedes Feld zufällig einen boolean generieren. Wenn dieser boolean true ist und du noch nicht alle Minen festgelegt hast hast du eine neue Mine
import java.util.Random;
Java:
 class Spielfeld{
     
        int laenge; //y hoehe
        int breite; //x breite
        int anzahl;
     
        Feld[][] EndeSF ;
     
        Spielfeld(int l, int b, int a){
            //Feldererstellung
            laenge = l;
            breite = b;
            anzahl = a;
            Feld[][] spfe = new Feld[breite][laenge];
            for(int h1=0;h1<laenge;h1++){
                for(int h2=0; h2<breite;h2++){
                    spfe[h2][h1] = new Feld();
                }
            }
            //Minenverteilung
            Random rand = new Random();
            for(int h1=0; h1<anzahl;h1++){
                int rb =rand.nextInt(breite);
                int rl = rand.nextInt(laenge);
                if(spfe[rb][rl].istMine==false){
                    spfe[rb][rl].setMine();
                    //linker Rand
                    if(rb!=0){
                        if(rl!=0){
                            spfe[rb-1][rl-1].setNachbar();
                         
                        }
                        if(rl!=laenge-1){
                            spfe[rb-1][rl+1].setNachbar();
                        }
                        spfe[rb-1][rl].setNachbar();
                    }
                    //rechter Rand
                    if(rb!=breite-1){
                        if(rl!=0){
                            spfe[rb+1][rl-1].setNachbar();
                        }
                        if(rl!=laenge-1){
                            spfe[rb+1][rl+1].setNachbar();
                         
                        }
                        spfe[rb+1][rl].setNachbar();
                    }
                    //oben und unten
                    if(rl!=0){
                        spfe[rb][rl-1].setNachbar();
                    }
                    if(rl!=laenge-1){
                        spfe[rb][rl+1].setNachbar();
                    }
                }
                else {
                    h1--;
                }
            }
            EndeSF=spfe;
        }
        public void printSPFE(){
            for(int h1=0;h1<laenge;h1++){
                System.out.print("\n");
                for(int h2=0; h2<breite;h2++){
                    System.out.print(EndeSF[h2][h1].printFeld()+" ");
             
                }
            }
        } 

    }
 
Für was denn? Versuch doch mal mit Worten zu erläutern, was jetzt gerade dein Problem ist 😉
endlich gemacht habe
Java:
class Feld{
      
    boolean istMine;//Eigenschaft
    boolean istgeoeffnet;
    int anzahlMine;
  
    Feld(){
        istMine = false; //konstruktur
        istgeoeffnet = false;
        anzahlMine = 0;
    }
  
    void setMine(){
        istMine= true; //Methode
    }
  
    boolean getMine(){
        return istMine;
    }
  
    void setgeoeffnet(){
        istgeoeffnet = true;
    }
    boolean getgeoeffnet(){
        return istgeoeffnet;
    }
  
    void setanzahl(int a){
        anzahlMine = a;
    }
  
    int getanzahl(int a){
        return anzahlMine;
    }
          
}






class Spielfeld{
    int h;
    int b;
    int am;
    Feld[][]s;
  
    Spielfeld(int h, int b, int am){
        this.h = h;
        this.b = b;
        this.am = am;
      
        s = new Feld[h][b];
      
        for(int i=0; i<h;i++){
            for(int j=0; j<b;j++){
                s[i][j] = new Feld();
            }
        }
        setMine();
        setanzahl();
    }
    public void setMine(){
        boolean anzahlMine = true;
        int counter = 0;
        if(am<=0){
            anzahlMine = false;
        }
        while(anzahlMine){
            int h = (int)(Math.random()*h);
            int b = (int)(Math.random()*b);  
            if(!s[h][b].getMine()){
                s[h][b].setMine();
                counter++;
            }
            if(counter == am){
                anzahlMine = false;
            }
        }
    }
  
  
    public void setanzahl(){
        for(int x = 0; x<s.length;x++){
            for(int y=0;y<s[0].length;y++){
                if(!s[x][y].getMine()){
                    int nachbar = 0;
                    if(x<s.length-1 && y>0 && s[x-1][y].getMine()){ // rechts
                        nachbar++;
                    }
                    if(x>0 && s[x-1][y].getMine()){// links
                        nachbar++;
                    }
                    if(x<s.length-1 && y>0 && s[x+1][y-1].getMine()){//hoch rechts
                        nachbar++;
                      
                    }
                    if(x>0 && y>0 && s[x-1][y-1].getMine()){ //hoch links
                        nachbar++;
                    }
                    if(y>0 && s[x][y-1].getMine()){ //hoch
                        nachbar++;
                    }
                  
                    if(y<s[0].length-1 && s[x][y+1].getMine()){// unten
                        nachbar++;
                    }
                    if(x<s.length-1 && y<s[0].length-1 && s[x+1][y+1].getMine()){ // unten rechts
                        nachbar++;
                    }
                    if(x>0 && y<s[0].length-1 && s[x+1][y+1].getMine()){ // unten links
                        nachbar++;
                    }
                  
                  
                  
                    s[x][y].setanzahl(nachbar);
                }
            }
        }
    }
    public void print(){
        for(int i=0; i<h; i++){
            System.out.print(" ");
            for(int j=0; j<b; j++){
                if(s[i][j].getMine()){
                    System.out.print(" * ");
                }else{
                    System.out.print(" "+s[i][j].getanzahl()+" ");
                }
            }
        }
    }
}


class Main{

    public static void main(String[] args) {
        Spielfeld a = new Spielfeld(5,5,10);//konstruktur
        a.print();
      
    }
}
 
Aber es zeigt mir nächste :
error: method getanzahl in class Feld cannot be applied to given types;
System.out.print(" "+s[j].getanzahl()+" ");
^
required: int
found: no arguments
reason: actual and formal argument lists differ in length
 
Es steht ja schon in der Fehlermeldung, dass deine Parameterliste der Methode getanzahl nicht mit der geforderten Parameterliste übereinstimmt.
Du deklarierst die Methode wie folgt int getanzahl(int) .. übergibst aber keinen.
Lange Rede kurzer Sinn: Entferne den Parameter bei der Methode
 
Java:
class Feld{
       
    boolean istMine;//Eigenschaft
    boolean istgeoeffnet;
    int anzahlMine;
   
    Feld(){
        istMine = false; //konstruktur
        istgeoeffnet = false;
        anzahlMine = 0;
    }
   
    void setMine(){
        istMine= true; //Methode
    }
   
    boolean getMine(){
        return istMine;
    }
   
    void setgeoeffnet(){
        istgeoeffnet = true;
    }
    boolean getgeoeffnet(){
        return istgeoeffnet;
    }
   
    void setanzahl(int a){
        anzahlMine = a;
    }
   
    int getanzahl(){
        return anzahlMine;
    }
           
}





/*
class Spielfeld{
    int h;
    int b;
    int am;
    Feld[][]s;
   
    Spielfeld(int h, int b, int am){
        this.h = h;
        this.b = b;
        this.am = am;
       
        s = new Feld[h][b];
       
        for(int i=0; i<h;i++){
            for(int j=0; j<b;j++){
                s[i][j] = new Feld();
            }
        }
        setMine();
        setanzahl();
    }
    public void setMine(){
        boolean anzahlMine = true;
        int counter = 0;
        if(am<=0){
            anzahlMine = false;
        }
        while(anzahlMine){
            int h = (int)(Math.random()*h);
            int b = (int)(Math.random()*b);   
            if(!s[h][b].getMine()){
                s[h][b].setMine();
                counter++;
            }
            if(counter == am){
                anzahlMine = false;
            }
        }
    }
   
   
    public void setanzahl(){
        for(int x = 0; x<s.length;x++){
            for(int y=0;y<s[0].length;y++){
                if(!s[x][y].getMine()){
                    int nachbar = 0;
                    if(x<s.length-1 && y>0 && s[x-1][y].getMine()){ // rechts
                        nachbar++;
                    }
                    if(x>0 && s[x-1][y].getMine()){// links
                        nachbar++;
                    }
                    if(x<s.length-1 && y>0 && s[x+1][y-1].getMine()){//hoch rechts
                        nachbar++;
                       
                    }
                    if(x>0 && y>0 && s[x-1][y-1].getMine()){ //hoch links
                        nachbar++;
                    }
                    if(y>0 && s[x][y-1].getMine()){ //hoch
                        nachbar++;
                    }
                   
                    if(y<s[0].length-1 && s[x][y+1].getMine()){// unten
                        nachbar++;
                    }
                    if(x<s.length-1 && y<s[0].length-1 && s[x+1][y+1].getMine()){ // unten rechts
                        nachbar++;
                    }
                    if(x>0 && y<s[0].length-1 && s[x+1][y+1].getMine()){ // unten links
                        nachbar++;
                    }
                   
                   
                   
                    s[x][y].setanzahl(nachbar);
                }
            }
        }
    }
    public void print(){
        for(int i=0; i<h; i++){
            System.out.print(" ");
            for(int j=0; j<b; j++){
                if(s[i][j].getMine()){
                    System.out.print(" * ");
                }else{
                    System.out.print(" "+s[i][j].getanzahl()+" ");
                }
            }
        }
    }
}
*/
/*
class Main{

    public static void main(String[] args) { 
        Spielfeld a = new Spielfeld(5,5,10);//konstruktur 
        a.print();
       
    }
}
*/
Ich habe folgendes Problem :
.\Spielfeld.java:29: error: variable h might not have been initialized
int h = (int)(Math.random()*h);
^
.\Spielfeld.java:30: error: variable b might not have been initialized
int b = (int)(Math.random()*b);
 
Ja, ist klar, du kannst nicht auf den Wert einer Variablen zugreifen, so lange sie nicht initialisiert wurde. Die Frage ist, wie immer, was möchtest Du denn als Ergebnis bekommen?

EDIT: hab gerade Deinen restlichen Code angesehen. Du musst auf der rechten Seite this.h und this.b verwenden.
 
Ja, ist klar, du kannst nicht auf den Wert einer Variablen zugreifen, so lange sie nicht initialisiert wurde. Die Frage ist, wie immer, was möchtest Du denn als Ergebnis bekommen?

EDIT: hab gerade Deinen restlichen Code angesehen. Du musst auf der rechten Seite this.h und this.b verwenden.
das habe ich schon verändert :
Java:
class Feld{
       
    boolean istMine;//Eigenschaft
    boolean istgeoeffnet;
    int anzahlMine;
   
    Feld(){
        istMine = false; //konstruktur
        istgeoeffnet = false;
        anzahlMine = 0;
    }
   
    void setMine(){
        istMine= true; //Methode
    }
   
    boolean getMine(){
        return istMine;
    }
   
    void setgeoeffnet(){
        istgeoeffnet = true;
    }
    boolean getgeoeffnet(){
        return istgeoeffnet;
    }
   
    void setanzahl(int a){
        anzahlMine = a;
    }
   
    int getanzahl(){
        return anzahlMine;
    }
           
}





/*
class Spielfeld{
    int h;
    int b;
    int am;
    Feld[][]s;
   
    Spielfeld(int h, int b, int am){
        this.h = h;
        this.b = b;
        this.am = am;
       
        s = new Feld[h][b];
       
        for(int i=0; i<h;i++){
            for(int j=0; j<b;j++){
                s[i][j] = new Feld();
            }
        }
        setMine();
        setanzahl();
    }
    public void setMine(){
        boolean anzahlMine = true;
        int counter = 0;
        if(am<=0){
            anzahlMine = false;
        }
        while(anzahlMine){
            int h = (int)(Math.random()*this.h);
            int b = (int)(Math.random()*this.b);   
            if(!s[h][b].getMine()){
                s[h][b].setMine();
                counter++;
            }
            if(counter == am){
                anzahlMine = false;
            }
        }
    }
   
   
    public void setanzahl(){
        for(int x = 0; x<s.length;x++){
            for(int y=0;y<s[0].length;y++){
                if(!s[x][y].getMine()){
                    int nachbar = 0;
                    if(x<s.length-1 && y>0 && s[x-1][y].getMine()){ // rechts
                        nachbar++;
                    }
                    if(x>0 && s[x-1][y].getMine()){// links
                        nachbar++;
                    }
                    if(x<s.length-1 && y>0 && s[x+1][y-1].getMine()){//hoch rechts
                        nachbar++;
                       
                    }
                    if(x>0 && y>0 && s[x-1][y-1].getMine()){ //hoch links
                        nachbar++;
                    }
                    if(y>0 && s[x][y-1].getMine()){ //hoch
                        nachbar++;
                    }
                   
                    if(y<s[0].length-1 && s[x][y+1].getMine()){// unten
                        nachbar++;
                    }
                    if(x<s.length-1 && y<s[0].length-1 && s[x+1][y+1].getMine()){ // unten rechts
                        nachbar++;
                    }
                    if(x>0 && y<s[0].length-1 && s[x+1][y+1].getMine()){ // unten links
                        nachbar++;
                    }
                   
                   
                   
                    s[x][y].setanzahl(nachbar);
                }
            }
        }
    }
    public void print(){
        for(int i=0; i<h; i++){
            System.out.print(" ");
            for(int j=0; j<b; j++){
                if(s[i][j].getMine()){
                    System.out.print(" * ");
                }else{
                    System.out.print(" "+s[i][j].getanzahl()+" ");
                }
            }
        }
    }
}
*/
/*
class Main{

    public static void main(String[] args) { 
        Spielfeld a = new Spielfeld(5,5,10);//konstruktur 
        a.print();
       
    }
}
*/
wenn ich eine Klasse Main aufrufe, besteht folgende Fehler :
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1
at Spielfeld.setanzahl(Spielfeld.java:47)
at Spielfeld.<init>(Spielfeld.java:20)
at Main.main(Main.java:4)
 
Ja, da Deine Schleifen bei 0 beginnen, musst Du natürlich sicherstellen, dass x > 0 bzw. y > 0 gilt, sobald Du auf Indizes x-1 bzw. y-1 zugreifst. Im ersten if in der Schleife von setanzahl fehlt z. B. der Test auf x > 0.
 
Ja, da Deine Schleifen bei 0 beginnen, musst Du natürlich sicherstellen, dass x > 0 bzw. y > 0 gilt, sobald Du auf Indizes x-1 bzw. y-1 zugreifst. Im ersten if in der Schleife von setanzahl fehlt z. B. der Test auf x > 0.
Also, ich brauche Hilfe, weil ich nicht ganz verstehe, was du meinst
Ich muss zuerst ein Programm Minesweeper - Daten schreiben.
Hier habe ich es geschrieben
Java:
class Feld{
       
    boolean istMine;//Eigenschaft
    boolean istgeoeffnet;
    int anzahlMine;
   
    Feld(){
        istMine = false; //konstruktur
        istgeoeffnet = false;
        anzahlMine = 0;
    }
   
    void setMine(){
        istMine= true; //Methode
    }
   
    boolean getMine(){
        return istMine;
    }
   
    void setgeoeffnet(){
        istgeoeffnet = true;
    }
    boolean getgeoeffnet(){
        return istgeoeffnet;
    }
   
    void setanzahl(int a){
        anzahlMine = a;
    }
   
    int getanzahl(){
        return anzahlMine;
    }
           
}





/*
class Spielfeld{
    int h;
    int b;
    int am;
    Feld[][]s;
   
    Spielfeld(int h, int b, int am){
        this.h = h;
        this.b = b;
        this.am = am;
       
        s = new Feld[h][b];
       
        for(int i=0; i<h;i++){
            for(int j=0; j<b;j++){
                s[i][j] = new Feld();
            }
        }
        setMine();
        setanzahl();
    }
    public void setMine(){
        boolean anzahlMine = true;
        int counter = 0;
        if(am<=0){
            anzahlMine = false;
        }
        while(anzahlMine){
            int h = (int)(Math.random()*this.h);
            int b = (int)(Math.random()*this.b);   
            if(!s[h][b].getMine()){
                s[h][b].setMine();
                counter++;
            }
            if(counter == am){
                anzahlMine = false;
            }
        }
    }
   
   
    public void setanzahl(){
        for(int x = 0; x<s.length;x++){
            for(int y=0;y<s[0].length;y++){
                if(!s[x][y].getMine()){
                    int nachbar = 0;
                    if(x<s.length-1 && y>0 && s[x-1][y].getMine()){ // rechts
                        nachbar++;
                    }
                    if(x>0 && s[x-1][y].getMine()){// links
                        nachbar++;
                    }
                    if(x<s.length-1 && y>0 && s[x+1][y-1].getMine()){//hoch rechts
                        nachbar++;
                       
                    }
                    if(x>0 && y>0 && s[x-1][y-1].getMine()){ //hoch links
                        nachbar++;
                    }
                    if(y>0 && s[x][y-1].getMine()){ //hoch
                        nachbar++;
                    }
                   
                    if(y<s[0].length-1 && s[x][y+1].getMine()){// unten
                        nachbar++;
                    }
                    if(x<s.length-1 && y<s[0].length-1 && s[x+1][y+1].getMine()){ // unten rechts
                        nachbar++;
                    }
                    if(x>0 && y<s[0].length-1 && s[x+1][y+1].getMine()){ // unten links
                        nachbar++;
                    }
                   
                   
                   
                    s[x][y].setanzahl(nachbar);
                }
            }
        }
    }
    public void print(){
        for(int i=0; i<h; i++){
            System.out.print(" ");
            for(int j=0; j<b; j++){
                if(s[i][j].getMine()){
                    System.out.print(" * ");
                }else{
                    System.out.print(" "+s[i][j].getanzahl()+" ");
                }
            }
        }
    }
}
*/
/*
class Main{

    public static void main(String[] args) { 
        Spielfeld a = new Spielfeld(5,5,10);//konstruktur 
        a.print();
       
    }
}
*/
Aber wie ich schon gesagt habe ,wenn ich eine Klasse Main aufrufe, besteht Fehler.
Außerdem brauche ich Minesweeper Test
Java:
class TestSpielFeld{
   
    public static void main(String[] args){
        new TestSpielFeld();
       
    }
   
    TestSpielFeld(){
        minenAnzahl();
        anzahlsetzen();
        testFelderAnzahl();
       
    }
   
    void minenAnzahl(){
        System.out.println("\n Test : MinenAnzahl stimmt");
        SpielFeld a = new SpielFeld(5,5 ,0 );
        int minen =0;
        for(int i=0; i<a.s.length;i++){
            for(int j=0; j<a.s[0].length;j++){
                if(a.s[i][j].getMine()){
                    minen++;
                }
            }
        }
        annahmeGleich(minen, 0);
       
        a = new
        SpielFeld(5,5 ,25 );
        minen =0;
        for(int i=0; i<a.s.length;i++){
            for(int j=0; j<a.s[0].length;j++){
                if(a.s[i][j].getMine()){
                    minen++;
                }
            }
        }
        annahmeGleich(minen, 25);
       
    }
   
    void anzahlsetzen(SpielFeld a){
        a.s[1][1].setzeMine();
        a.s[3][2].setzeMine();
        a.s[2][3].setzeMine();
        a.s[0][4].setzeMine();
        a.setAnzahl();
        a.print();
    }
   
    void testFelderAnzahl(){
        SpielFeld a = new SpielFeld(5,5 ,0);
        anzahlsetzen(a);
        System.out.println("\n Test : stimmmen die Zahlen in den Felder");
        annahmeGleich(a.s[1][4].getAnzahl(),2);
        annahmeGleich(a.s[4][0].getAnzahl(),0);
        annahmeGleich(a.s[0][2].getAnzahl(),1);
    }
   
    void annahmeGleich(int ist , int soll){
        if(ist == soll){
            System.out.println("Test : ok");
        }
        else
        System.out.println("Test : nicht ok");
    }
   
}
Das habe ich schon auch geschrieben
Und jetzt stellt sich mir eine grobe Frage, wie soll ich das alles zusammen verbinden?
 
Hier
Java:
for(int x = 0; x<s.length;x++){
fängst Du mit x = 0 an und hier
Java:
if(x<s.length-1 && y>0 && s[x-1][y].getMine()){ // rechts
greifst Du auf s[x-1], also s[-1] zu.
 
Du fängst ganz links auf dem Spielfeld an und prüfst:
Java:
if(x<s.length-1 && y>0 && s[x-1][y].getMine()){ // rechts
Du prüfst aber nicht nach rechts (s[x+1]) sondern nach links (s[x-1]). Und nachdem Du schon ganz links stehst, gibt es einen Fehler.
 
Du fängst ganz links auf dem Spielfeld an und prüfst:
Java:
if(x<s.length-1 && y>0 && s[x-1][y].getMine()){ // rechts
Du prüfst aber nicht nach rechts (s[x+1]) sondern nach links (s[x-1]). Und nachdem Du schon ganz links stehst, gibt es einen Fehler.
Ist es so richtig?
Java:
                    if(x>0 && y>0 && s[x-1][y-1].getMine()){ //hoch links
                        nachbar++;
                    }
                    if(x>0 && y<s[0].length-1 && s[x-1][y+1].getMine()){ // unten links
                        nachbar++;
                    }
                    if(x>0 && s[x-1][y].getMine()){// links
                        nachbar++;
                    }
                    if(x<s.length-1 && y>0 && s[x+1][y-1].getMine()){//hoch rechts
                        nachbar++;
                      
                    }
                    if(x<s.length-1 && y<s[0].length-1 && s[x+1][y+1].getMine()){ // unten rechts
                        nachbar++;
                    }
                    if(x<s.length-1 && y>0 && s[x+1][y].getMine()){ // rechts
                        nachbar++;
                    }
                  
                    if(y>0 && s[x][y-1].getMine()){ //hoch
                        nachbar++;
                    }
                  
                    if(y<s[0].length-1 && s[x][y+1].getMine()){// unten
                        nachbar++;
                    }
 
Zumindest sollte hier Exception mehr auftreten.
Java:
if(x<s.length-1 && y>0 && s[x+1][y].getMine()){ // rechts
Da bräuchtest Du && y > 0 nicht.
 
jetzt brauche ich Minesweeper Test zum Testen der Klasse Spielfeld. Dabei ist darauf zu achten, dass die Zufallszahlen im Programm keinen Einfluss auf das Testergebnis haben. Sie können dazu z.B. die Minen durch einen Befehl ihres Testprogramms an eine konkrete Stelle legen und dann prüfen, ob das die gewünschten Auswirkungen hatte:  Sind wirklich genauso viele Mienen vorhanden, wie angegeben wurden?  Stimmen die Zahlen in den Feldern?  Testen Sie mit unterschiedlichen Eingabewerten
Java:
class TestSpielFeld{
   
    public static void main(String[] args){
        new TestSpielFeld();
       
    }
   
    TestSpielFeld(){
        minenAnzahl();
        anzahlsetzen();
        testFelderAnzahl();
       
    }
   
    void minenAnzahl(){
        System.out.println("\n Test : MinenAnzahl stimmt");
        SpielFeld a = new SpielFeld(5,5 ,0 );
        int minen =0;
        for(int i=0; i<a.s.length;i++){
            for(int j=0; j<a.s[0].length;j++){
                if(a.s[i][j].getMine()){
                    minen++;
                }
            }
        }
        annahmeGleich(minen, 0);
       
        a = new
        SpielFeld(5,5 ,25 );
        minen =0;
        for(int i=0; i<a.s.length;i++){
            for(int j=0; j<a.s[0].length;j++){
                if(a.s[i][j].getMine()){
                    minen++;
                }
            }
        }
        annahmeGleich(minen, 25);
       
    }
   
    void anzahlsetzen(SpielFeld a){
        a.s[1][1].setzeMine();
        a.s[3][2].setzeMine();
        a.s[2][3].setzeMine();
        a.s[0][4].setzeMine();
        a.setAnzahl();
        a.print();
    }
   
    void testFelderAnzahl(){
        SpielFeld a = new SpielFeld(5,5 ,0);
        anzahlsetzen(a);
        System.out.println("\n Test : stimmmen die Zahlen in den Felder");
        annahmeGleich(a.s[1][4].getAnzahl(),2);
        annahmeGleich(a.s[4][0].getAnzahl(),0);
        annahmeGleich(a.s[0][2].getAnzahl(),1);
    }
   
    void annahmeGleich(int ist , int soll){
        if(ist == soll){
            System.out.println("Test : ok");
        }
        else
        System.out.println("Test : nicht ok");
    }
   
}
Das habe ich schon geschrieben aber wenn ich TestSpielFeld aufrufe,besteht folgendes Problem
TestSpielFeld.java:42: error: cannot find symbol
void anzahlsetzen(SpielFeld a){
^
symbol: class SpielFeld
location: class TestSpielFeld
TestSpielFeld.java:10: error: method anzahlsetzen in class TestSpielFeld cannot be applied to given types;
anzahlsetzen();
^
required: SpielFeld
found: no arguments
reason: actual and formal argument lists differ in length
TestSpielFeld.java:17: error: cannot find symbol
SpielFeld a = new SpielFeld(5,5 ,0 );
^
symbol: class SpielFeld
location: class TestSpielFeld
TestSpielFeld.java:17: error: cannot find symbol
SpielFeld a = new SpielFeld(5,5 ,0 );
^
symbol: class SpielFeld
location: class TestSpielFeld
TestSpielFeld.java:29: error: cannot find symbol
SpielFeld(5,5 ,25 );
^
symbol: class SpielFeld
location: class TestSpielFeld
TestSpielFeld.java:52: error: cannot find symbol
SpielFeld a = new SpielFeld(5,5 ,0);
^
symbol: class SpielFeld
location: class TestSpielFeld
TestSpielFeld.java:52: error: cannot find symbol
SpielFeld a = new SpielFeld(5,5 ,0);
^
symbol: class SpielFeld
location: class TestSpielFeld
7 errors

C:\Java>
 
Deine Klasse heißt Spielfeld und nicht SpielFeld. Ändere das in TestSpielFeld.java ab.
Java:
class TestSpielfeld{
   
    public static void main(String[] args){
        new TestSpielfeld();
       
    }
   
    TestSpielfeld(){
        minenAnzahl();
        anzahlsetzen();
        testFelderAnzahl();
       
    }
   
    void minenAnzahl(){
        System.out.println("\n Test : MinenAnzahl stimmt");
        Spielfeld a = new Spielfeld(5,5 ,0 );
        int minen =0;
        for(int i=0; i<a.s.length;i++){
            for(int j=0; j<a.s[0].length;j++){
                if(a.s[i][j].getMine()){
                    minen++;
                }
            }
        }
        annahmeGleich(minen, 0);
       
        a = new
        Spielfeld(5,5 ,25 );
        minen =0;
        for(int i=0; i<a.s.length;i++){
            for(int j=0; j<a.s[0].length;j++){
                if(a.s[i][j].getMine()){
                    minen++;
                }
            }
        }
        annahmeGleich(minen, 25);
       
    }
   
    void anzahlsetzen(Spielfeld a){
        a.s[1][1].setzeMine();
        a.s[3][2].setzeMine();
        a.s[2][3].setzeMine();
        a.s[0][4].setzeMine();
        a.setAnzahl();
        a.print();
    }
   
    void testFelderAnzahl(){
        Spielfeld a = new Spielfeld(5,5 ,0);
        anzahlsetzen(a);
        System.out.println("\n Test : stimmmen die Zahlen in den Felder");
        annahmeGleich(a.s[1][4].getAnzahl(),2);
        annahmeGleich(a.s[4][0].getAnzahl(),0);
        annahmeGleich(a.s[0][2].getAnzahl(),1);
    }
   
    void annahmeGleich(int ist , int soll){
        if(ist == soll){
            System.out.println("Test : ok");
        }
        else
        System.out.println("Test : nicht ok");
    }
   
}
ich habe verändert aber das funktioniert nicht
 
Du erstellst in testFelderAnzahl() ein Objekt von Spielfeld und in minenAnzahl() sogar gleich 2 mal .. das kann nicht funktionieren.
Du brauchst ein und das selbe Objekt für alle Methoden dieser Klasse.
 
Du erstellst in testFelderAnzahl() ein Objekt von Spielfeld und in minenAnzahl() sogar gleich 2 mal .. das kann nicht funktionieren.
Du brauchst ein und das selbe Objekt für alle Methoden dieser Klasse.
Java:
class TestSpielfeld{
   
    public static void main(String[] args){
        new TestSpielfeld();
       
    }
   
    TestSpielfeld(){
        minenAnzahl();
        //anzahlsetzen();
        testFelderAnzahl();
       
    }
   
    void minenAnzahl(){
        System.out.println("\n Test : MinenAnzahl stimmt");
        Spielfeld a = new Spielfeld(5,5 ,0 );
        int minen =0;
        for(int i=0; i<a.s.length;i++){
            for(int j=0; j<a.s[0].length;j++){
                if(a.s[i][j].getMine()){
                    minen++;
                }
            }
        }
        annahmeGleich(minen, 0);
       
        a = new
        Spielfeld(5,5 ,25 );
        minen =0;
        for(int i=0; i<a.s.length;i++){
            for(int j=0; j<a.s[0].length;j++){
                if(a.s[i][j].getMine()){
                    minen++;
                }
            }
        }
        annahmeGleich(minen, 25);
       
    }
   
    void anzahlsetzen(Spielfeld a){
        a.s[1][1].setzeMine();
        a.s[3][2].setzeMine();
        a.s[2][3].setzeMine();
        a.s[0][4].setzeMine();
        a.setanzahl();
        //a.print();
    }
   
    void testFelderAnzahl(){
        Spielfeld a = new Spielfeld(5,5 ,0);
        anzahlsetzen(a);
        System.out.println("\n Test : stimmmen die Zahlen in den Felder");
        annahmeGleich(a.s[1][4].getanzahl(),2);
        annahmeGleich(a.s[4][0].getanzahl(),0);
        annahmeGleich(a.s[0][2].getanzahl(),1);
    }
   
    void annahmeGleich(int ist , int soll){
        if(ist == soll){
            System.out.println("Test : ok");
        }
        else
        System.out.println("Test : nicht ok");
    }
   
}
So jetzt funktioniert
upload_2018-12-17_16-45-23.png
aber wenn ich //anzahlsetzen(); aktiviert habe, zeigt mir folgende
 

Anhänge

  • upload_2018-12-17_16-45-15.png
    upload_2018-12-17_16-45-15.png
    73,2 KB · Aufrufe: 16
  • upload_2018-12-17_16-45-15.png
    upload_2018-12-17_16-45-15.png
    73,2 KB · Aufrufe: 24
  • upload_2018-12-17_16-50-11.png
    upload_2018-12-17_16-50-11.png
    107,7 KB · Aufrufe: 20
Man kann im übrigen auch in der Eingabeaufforderung markieren, kopieren und hier als Text einfügen. Dann brauchst Du keine zig Screenshots einzustellen.
 
Ich habe eine Frage und zwar, Ich habe hier eine Methode „linksKlick(int x, int y)“ geschrieben. Und jetzt soll ich
meine Implementierung testen, indem man für linksKlick und ggf. weitere Prozeduren geeignete Testmethoden in Testprogramm .Dazu braucht man Situationen, die wiederherstellbar sind. Hier ist das zufällige Verteilen der Minen natürlich nicht geeignet…
Wie kann man das realisieren?

Java:
class Spielfeld{
    int h;
    int b;
    int am;
    Feld[][]s;
 
    Spielfeld(int h, int b, int am){
        this.h = h;
        this.b = b;
        this.am = am;
     
        s = new Feld[h][b];
     
        for(int i=0; i<h;i++){
            for(int j=0; j<b;j++){
                s[i][j] = new Feld();
            }
        }
        setMine();
        setanzahl();
    }
    public void setMine(){
        boolean anzahlMine = true;
        int counter = 0;
        if(am<=0){
            anzahlMine = false;
        }
        while(anzahlMine){
            int h = (int)(Math.random()*this.h);
            int b = (int)(Math.random()*this.b); 
            if(!s[h][b].getMine()){
                s[h][b].setMine();
                counter++;
            }
            if(counter == am){
                anzahlMine = false;
            }
        }
    }
 
 
    public void setanzahl(){
        for(int x = 0; x<s.length;x++){
            for(int y=0;y<s[0].length;y++){
                if(!s[x][y].getMine()){
                    int nachbar = 0;
                    if(x>0 && y>0 && s[x-1][y-1].getMine()){ //hoch links
                        nachbar++;
                    }
                    if(x>0 && y<s[0].length-1 && s[x-1][y+1].getMine()){ // unten links
                        nachbar++;
                    }
                    if(x>0 && s[x-1][y].getMine()){// links
                        nachbar++;
                    }
                    if(x<s.length-1 && y>0 && s[x+1][y-1].getMine()){//hoch rechts
                        nachbar++;
                     
                    }
                    if(x<s.length-1 && y<s[0].length-1 && s[x+1][y+1].getMine()){ // unten rechts
                        nachbar++;
                    }
                    if(x<s.length-1 &&  s[x+1][y].getMine()){ // rechts
                        nachbar++;
                    }
                 
                    if(y>0 && s[x][y-1].getMine()){ //hoch
                        nachbar++;
                    }
                 
                    if(y<s[0].length-1 && s[x][y+1].getMine()){// unten
                        nachbar++;
                    }
                 
                 
                 
                 
                 
                    s[x][y].setanzahl(nachbar);
                }
            }
        }
    }
    public void print(){
        for(int i=0; i<h; i++){
            System.out.println(" ");
            for(int j=0; j<b; j++){
                String z = "?";
                if(s[i][j].getgeoeffnet())
                    z = "+";
                else
                    z = "-";
                if(s[i][j].getMine()){
                    System.out.print(" *"+z);
                }else{
                    System.out.print(" "+s[i][j].getanzahl()+z);
                }
            }
        }
    }
    public void linksKlick(int x, int y){
         
            if(x>=0 && y>=0 && x< s.length && y<s[0].length){
                if(s[x][y].istgeoeffnet == false) {
                   s[x][y].istgeoeffnet = true;
             
                    if(s[x][y].getMine()){
                     
                        System.out.println("Verloren");// in neue Methode ausgliedern
                    }
             
                    if(s[x][y].anzahlMine == 0){
                        linksKlick(x -1, y -1);
                        linksKlick(x -1, y +1);
                        linksKlick(x -1, y);
                        linksKlick(x +1, y -1);
                        linksKlick(x +1, y +1);
                        linksKlick(x +1, y );     
                        linksKlick(x , y -1);
                        linksKlick(x , y +1);
                }
                }
            }
        }
}
 
Wie kann man das realisieren?
Zum Beispiel mit einem Konstruktor, der ein initialisiertes Array entgegennimmt. Andere Möglichkeit wäre, die Klasse Random zu verwenden und mit einem Seed zu initialisieren.

Deine setMine-Methode grenzt übrigens an Obfuscation. Witzig ist auch, dass Du die Instanzvariable mit einem nichtssagenden "am" bezeichnest, in setMine dagegen einen an sich aussagekräftigen Bezeichner "anzahlMine" verwendest, der aber völlig irreführend ist.
 

Zurück
Oben