Minesweeper-Problem

EmmaM95

Mitglied
Hallo ich muss für die Uni ein Minesweeper Programm schreiben, jetzt fehlt mir aber noch eine Klasse bevor ich es abgeben kann. Die Aufgabenstellung sieht so aus:

public boolean hasWon()
Signalisiert das Ende eines Spieles: true, falls alle Felder ohne Mine geöffnet wurden.
public int getRemainingMines() Berechnet die Anzahl der noch verbleibenden Minen. Dazu wird von der Gesamtzahl der Minen, die Anzahl der mit einer Flagge versehenen Felder abgezogen.

 public RevealFieldsResult revealFields(Coordinate coord) Diese Methode deckt ein vom Benutzer mit einem Linksklick ausgewähltes Feld nach folgenden Regeln auf:
o Feld als aufgedeckt markieren (setOpened)
o Feld ist eine Mine: Game Over <=> FOUND_MINE
o Feld ist keine Mine:
 Feld hat keine Nachbarn die vermient sind:
 Aufdecken aller Felder die mit diesem Feld benachbart sind
 Feld hat Nachbarn die vermient sind (getNeighbourMineCount != 0) -> keine weitere Aktion

 public RevealFieldsResult revealMultiClickFields(Coordinate coord)
Mit dieser Methode ist es möglich alle Nachbarn des bereits offenen Feldes an den gegebenen Koordinaten aufzudecken. Dabei gelten folgende Regeln:
o Ist das Feld noch nicht geöffnet, passiert nichts (FIELD_NOT_REVEALED).
o Ist das Feld geöffnet und es grenzt an keine Mine an, passiert nichts (FIELD_NOT_REVEALED).
o Ist das Feld geöffnet und es grenzt an mindestens eine Mine an, wird unterschieden:
 Stimmt die Anzahl der Flaggen auf den Nachbarfeldern mit der Anzahl der Minen überein, werden alle Felder die KEINE Flagge haben aufgedeckt (siehe revealFields-Methode).
 Stimmt die Anzahl der Flaggen auf den Nachbarfeldern nicht mit der Anzahl der Minen überein, passiert nichts (FIELD_NOT_REVEALED). Achtung: Ist also mindestens eine Flagge falsch gesetzt, ist das Spiel verloren, da Minen aufgedeckt werden.


Ich hab schon ein Anfang, aber komme nicht mehr weiter.

Java:
public class Board {

    private int remainingMines;
    private Collection<Field> mines;
    private Collection<Field> fields;
    private int width;
    private boolean hasWon;
    private int height;
 

    public Board(int width, int height, Collection<Coordinate> mines){
         Collection<Field> fields = new ArrayList<Field>();
      
      
      
          for(int x = 0; x < width; x++) {
           for(int y = 0; y < height; y++) {
            
             Field field = new Field(new Coordinate(x, y));
          
             if(field.hasMine()==true) {    
              field.setHasMine(true);
             } else {
              field.setNeighbourMineCount(count);
             }
            fields.add(field);
         
           }
          }
      
          this.fields = fields;
     
    }
 
    public boolean getHasWon(){
        return hasWon;
    }
 
    public int getWidth() {
        return width;
    }


    public int getHeight() {
        return height;
    }


    public boolean hasWon(){
        if(remainingMines==0){
            return true;
        }
        return false;
    }
 
    public void flagMine(Coordinate coord){
        for(Field field: getFields()){
            if(field.getCoordinate().equals(coord)){
                if( field.hasFlag==true&&field.isOpened==false){
                field.setHasFlag(false);
             
            }
            else if( field.hasFlag==false&&field.isOpened==false){
                field.setHasFlag(true);
            }
            }
             
        }
    }
 
    public int getRemainingMines(){
        return remainingMines;
    }
 
    public Collection<Field> getMines(){
        return mines;
    }
 
    public Collection<Field> getFields(){
        return Collections.unmodifiableCollection(fields);
    }
/*Diese letzten Methoden machen die meisten Probleme weil ich nicht weiß wie ich sie umsetzen soll  */

    public RevealFieldsResult revealFields(Coordinate coord){
        for(Field field: getFields()){
            if(field.isOpened==false){
                field.setOpened(true);
            }
            if(field.hasMine==true){
                return null ; // return null nur provisorisch
            }
            if(field.hasMine==false){
                if(field.getNeighbourMineCount()==0){
                 
                }
                else{
                 
                }
            }
        }
            return null; //return null nur provisorisch
     
    }
 
    public RevealFieldsResult revealMultiClickFields(Coordinate coord){
        return null; //return null nur provisorisch
    }
}



Vielen Dank im Voraus
 
Also mittlerweile habe ich die ganze Klasse fertig. Aber irgendwo sind Fehler. Könnte da mal jemand drüber schauen?
Java:
public class Board {
    protected Collection<Field> fields;
    protected Collection<Field> mines;
  
    //Konstruktor
    public Board(int width, int height, Collection<Coordinate> mines){
        Collection<Field> fields = new HashSet<Field>();
      
        for(int x = 0; x < width; x++) {
            for(int y = 0; y < height; y++) {
                Coordinate coord = new Coordinate(x, y);
                Field field = new Field(coord);
                if(true == mines.contains(coord)) {
                    field.setHasMine(true);
                    mines.add(coord);
                }
                fields.add(field);
            }
        }
        this.fields = fields;
    }
  
  
    public boolean hasWon(){
         boolean result = false;
         if(this.getRemainingMines() != 0) {
             result = false;
         } else {
             result = true;
             for(Field field : this.getFields()) {
                 if( ((true == field.hasMine()) && (true == field.hasFlag())) ||
                         ((false == field.hasMine()) && (true == field.isOpened()))
                 ) {} else {
                     result = false;
                 }
             }
         }
         return result;
    }
  
    /*An der übergebenen Koordinate wird eine Flagge gesetzt, wenn noch keine gesetzt wurde.
     * Im Fall, dass schon eine gesetzt wurde, wird sie entfernt!
     */
    public void flagMine(Coordinate coord){
           for(Field field : this.getFields()) {
               if(true == field.getCoordinate().equals(coord)) {
                   if(true == field.isOpened()) {
                   } else {
                       field.setHasFlag(!field.hasFlag());
                   }
                   break;
               }
           }

    public int getRemainingMines(){
         int count = getMines().size();
         for(Field field : this.getFields()) {
             if(true == field.hasFlag()) {
                 count--;
             }
         }
         return count;
    }
  
    public Collection<Field> getMines(){
        return mines;
    }
  
    public Collection<Field> getFields(){
        return Collections.unmodifiableCollection(fields);
            }
  
    public RevealFieldsResult revealFields(Coordinate coord)
    {
        for(Field field : this.getFields()) {
            if(true == field.getCoordinate().equals(coord)) {
                field.setOpened(true);
                if(true == field.hasMine()) {
                    return new RevealFieldsResult(new HashSet<Field>());
                } else {
                    if(field.getNeighbourMineCount() == 0) {
                        Collection<Field> fields = new HashSet<Field>();

                        fields.add(
                                new Field(new Coordinate(field.getCoordinate(),1,-1))
                        );
                        fields.add(
                                new Field(new Coordinate(field.getCoordinate(),1,0))
                        );
                        fields.add(
                                new Field(new Coordinate(field.getCoordinate(),1,1))
                        );

                        fields.add(
                                new Field(new Coordinate(field.getCoordinate(),0,-1))
                        );
                        fields.add(
                                field
                        );
                        fields.add(
                                new Field(new Coordinate(field.getCoordinate(),0,1))
                        );

                        fields.add(
                                new Field(new Coordinate(field.getCoordinate(),-1,-1))
                        );
                        fields.add(
                                new Field(new Coordinate(field.getCoordinate(),-1,0))
                        );
                        fields.add(
                                new Field(new Coordinate(field.getCoordinate(),-1,1))
                        );
                        fields.add(
                                new Field(new Coordinate(field.getCoordinate(),0,0))
                                );
                      


                        return new RevealFieldsResult(fields);
                    } else {
                        return new RevealFieldsResult(fields);
                    }
                }
            }
        }
        return new RevealFieldsResult(fields);
    }
   
    // Mit dieser Methode ist es möglich alle Nachbarn des bereits offenen Feldes an den gegebenen Koordinaten aufzudecken
    public RevealFieldsResult revealMultiClickFields(Coordinate coord)
    {
  
        for(Field field : this.getFields()){
             if(true == field.getCoordinate().equals(coord)){
                 if(field.isOpened==false){
                     return new RevealFieldsResult();
                 }
                 else {if(field.isOpened&&field.getNeighbourMineCount()==0){
                     return new RevealFieldsResult();
                 }
                 else{
                     if(this.getRemainingMines()==0){
                         if(field.hasFlag==false){
                             field.setOpened(true);
                         }
                     }
                     else{
                         if(this.getRemainingMines()!=0){
                             return new RevealFieldsResult();
                         }
                     }
                     }
             }
        }
    }
        return new RevealFieldsResult();
 
Zuletzt bearbeitet von einem Moderator:
Ich muss das Programm in ei Portal hochladen und dieses macht dann Test und ein paar Test besteht es noch nicht.
Hier sind die Fehlermeldungen:
1.
testFlagMineAndGetRemainingMines
Cause of failure:
java.lang.NullPointerException
at de.uniwue.jpp.minesweeper.model.Board.getRemainingMines(Board.java:90)
at de.uniwue.jpp.minesweeper.tests.model.required.BoardTest.testFlagMineAndGetRemainingMines(BoardTest.java:147)

2.
testInitializationAndGetMines
Cause of failure:
java.lang.NullPointerException
at de.uniwue.jpp.minesweeper.tests.model.required.BoardTest.testInitializationAndGetMines(BoardTest.java:130)

3.
testInitializationAndNeighbourMineCount
Cause of failure:
java.lang.AssertionError: After initialization field

Field {
coordinate = (1/1)
hasFlag = false
hasMine = false
isOpened = false
neighbourMineCount = 0
}

did not give the correct neighbourMineCount. Board:

3 3

| | | |
| | |m|
| |m| |

|#|#|#|
|#|#|#|
|#|#|#|
Expected: <2>
but: was <0>
at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
at org.junit.Assert.assertThat(Assert.java:865)
at de.uniwue.jpp.minesweeper.tests.model.required.BoardTest.testInitializationAndNeighbourMineCount(BoardTest.java:85)

4.
testMultiClickWrongGuess
Cause of failure:
java.lang.AssertionError: Revealing field at coordinates (2/1) gave result with wrong state. Board before:

3 3

| | | |
| | | |
| |m|m|

|#|#|#|
|#|f| |
|#|#|f|

Board after:

3 3

| | | |
| | | |
| |m|m|

Status:
|#|#|#|
|#|f| |
|#|#|f|
Expected: <FOUND_MINE>
but: was <FIELD_NOT_REVEALED>
at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
at org.junit.Assert.assertThat(Assert.java:865)
at de.uniwue.jpp.minesweeper.tests.model.required.BoardTest.testMultiClickWrongGuess(BoardTest.java:386)

5.
testRevealFields3x3MultipleFields
Cause of failure:
java.lang.AssertionError: Revealing field at coordinates (0/0) gave result with wrong number of fields. Board before:

3 3

| | | |
| | |m|
| |m| |

|#|#|#|
|#|#|#|
|#|#|#|

Board after:

3 3

| | | |
| | |m|
| |m| |

Status:
| |#|#|
|#|#|#|
|#|#|#|
Expected: <4>
but: was <10>
at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
at org.junit.Assert.assertThat(Assert.java:865)
at de.uniwue.jpp.minesweeper.tests.model.required.BoardTest.testRevealFields3x3MultipleFields(BoardTest.java:221)


Ich habe noch andere Klassen, die zur Aufgabe gehören, falls du denkst das eine davon ein Fehler enthält kann ich sie kurz hochladen
 
Zu 1 & 2. du hast in deinem Konstruktor mines nicht gesetzt deshalb flieg die Exception.

Die anderen Fehler entstehen Wahrscheinlich deshalb.
 
Hab ich gemacht. Das Problem ist ich hab einmal Collection<Coordinate> mines im Konstruktor und einmal public Collection<Field> getMines(). Ich habe jetzt keine Ahnung wie ich das machen soll
 
Ups Tschuldige hab übersehen das es sich einmal um eine Collection vom Typ Coordinate und einmal vom Typ Field Handelt. Dann musst du in deinem Konstruktor für jede Coodinate ein entsprechendes Field erstellen und das denn der Collection hinzufügen. und natürlich vorher mines initialisieren mit this.mines = [was auch immer du hier für eine Collection wählen willst]
 
OK noch mal langsam. Du hast eine Collection<Field> instanzvariable mines (imfolgenden this.mines genannt) und du hast ein Konstruktor mit einem Übergabeparameter mines vom Typ Collection<Coordinate>.
Das erste was du jetzt machen musst ist this.mines initsialisieren.
Danach kannst du mines durchgehen und für jedes Coodrinate Object was enthalten ist ein neues Field erstellen und dieses neue Field dann this.mines hinzufügen.
In pseudocode in etwa so
Code:
this.mines = createNewCollection();
for(Coodrinate c in mines) {
  Field newField = createNewField(c);
  this.mines.add(newField);
}
 

Zurück
Oben