Minesweeper Java

btl1903

Mitglied
Hallo! Ich muss das Spiel Minesweeper in Java programmieren. Da ich nicht so gut beim Programmieren bin, habe ich keine Idee, wie ich überhaupt anfangen soll.

Die Angabe lautet so:

Stick to the following format:

Sample input Sample output
(from file) (to System.out)

4 4 Field: 1
*... *100
.... 2210
.*.. 1*10
.... 1110
3 5 Field: 2
**... **100
..... 33200
.*... 1*100
0 0 22


Additionally, your programm shall implement the following interface, where the return value of the method minesweep shall be the sum of all integers in the output fields (for the example above, this is 22):

import java.io.File;

public interface Assignment1 {
public long minesweep(File inputfile);
}

Note: do not use the Java 'package' statement.

Wie sollte ich anfangen oder was sollte ich grundsätzlich machen?
 

krgewb

Top Contributor
Deine Werte in Monospace-Schrift:
Code:
4 4 Field:

*...  *100
....  2210
.*..  1*10
....  1110


3 5 Field:

**...  **100
.....  33200
.*...  1*100

So wie ich das verstehe musst du kein spielbares Spiel programmieren sondern nur das Feld mit den Ziffern ausgeben.
In der Datei, die gegeben ist sind nur Punkte und Sterne. Punkte stehen für sichere Felder. Sterne stehen für Minen.
Hier gibt es solch eine Aufgabenstellung auf deutsch, sogar mit denselben Zahlen: http://www.programmierkurs-java.de/materialien/Aufgaben/UE17-Aufgaben.pdf (Aufgabe 43).
 
Zuletzt bearbeitet:

btl1903

Mitglied
ich hab derzeit folgenden Code:

Java:
import java.io.File;
import java.io.*;
import java.util.Scanner;

public interface Assignment1 {
    public long minesweep(File inputfile);
  

    public static void main(String[] args) throws FileNotFoundException  {

        Scanner in = null;
       
        try{
            in  = new Scanner(new BufferedReader(new FileReader("input.txt")));
  
            int zaehler=1;
            char [][] feld;
            int width;
            int height;

            while(in.hasNextLine()){
                if(in.hasNextInt()){
                    int i = in.nextInt();
                    int j = in.nextInt();
                    feld = new char [i][j];
                    width=i;
                    height=j;
                    System.out.println("Field:" + zaehler);   
                    zaehler++;
                }
              
                else{
                    in.nextLine();
                    if (in.hasNext()){
                        String a=in.next();
                        System.out.println(a);
                    }
                }
            }    
        }
        finally{
            in.close(); 
        }          
    }
}

Hab ein Zähler für die Angabe der Felder. Danach liest das Programm die input file und gibt eigentlich nur die gleiche Eingabe wieder aus. Ich komme nicht weiter, wie ich jetzt zu den Zahlen kommen soll. Da muss ich ja die 8 Nachbarfelder überprüfen und die Zahl der Mienen angeben. Aber wie soll ich das machen? Derzeit wo steht "Field: 3" muss am Ende die Summe aller ganzen Zahlen in der Ausgabe stehen.
 

krgewb

Top Contributor
Danach liest das Programm die input file und gibt eigentlich nur die gleiche Eingabe wieder aus.
Dein Programm müsste demnach
Code:
*...
....
.*..
....
ausgeben aber derzeit gibt es folgendes aus:
Code:
....
.*..
....
Es fehlt also die erste Zeile. Ich helfe dir per PN.
 
Zuletzt bearbeitet:

krgewb

Top Contributor
input.txt:
Code:
**...
.....
.*...

Assignment1:
Java:
package de.hrw;

import java.io.*;

public interface Assignment1 {
    public long minesweep(File inputfile);

    public static void main(String[] args) throws FileNotFoundException {

        int height = 0;
        int width = 0;
        BufferedReader br;

        // Die Datei wird eingelesen damit die height und width herausgefunden
        // werden koennen.
        // Dies ist notwendig, weil Hoehe und Breite von Arrays nachtraeglich
        // nicht
        // vergroessert werden koennen.

        try {
            br = new BufferedReader(new FileReader("input.txt"));
            try {
                String x;

                // Die Schleife wird fuer alle Zeilen in der Datei
                // durchlaufen.
                while ((x = br.readLine()) != null) {
                    if (x.equals("") == false) {
                        // Anzahl der Zeilen um 1 erhoehen.
                        height++;
                        // Anzahl der Spalten setzen.
                        width = x.length();
                    }
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        } catch (FileNotFoundException ex) {
            ex.printStackTrace();
        }

        if (height == 0) {
            System.out.println("FEHLER. Die Anzahl der Spalten ist 0.");
            return;
        }

        if (width == 0) {
            System.out.println("FEHLER. Die Anzahl der Spalten ist 0.");
            return;
        }

        char[][] feld = new char[height][width];

        // Die Datei wird noch einmal eingelesen und die Zeichen werden
        // in dem feld-Array gespeichert.

        try {
            br = new BufferedReader(new FileReader("input.txt"));
            try {
                String x;

                // i ist die Nummer der Spalte
                int i = 0;

                // Die Schleife wird fuer alle Zeilen in der Datei
                // durchlaufen.
                while ((x = br.readLine()) != null) {
                    if (x.equals("") == false) {
                        // j ist der index des Zeichens (ganz links = 0)
                        for (int j = 0; j < x.length(); j++) {
                            // Zeichen in das Array speichern.
                            feld[i][j] = x.charAt(j);
                        }

                        i++;
                    }
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        } catch (FileNotFoundException ex) {
            ex.printStackTrace();
        }

        // Fuer das neue Array wird int als Datentyp verwendet.
        // Alternativ kann mit einem char-Array und ASCII-Tabelle
        // ( http://www.chip.de/ii/1/2/5/4/9/5/8/0/ascii-93c823e7009f26b0.png )
        // gearbeitet werden.
        int[][] feldNEU = new int[height][width];

        // Nun wird fuer jedes Kaestchen geschaut, wieviele Nachbar-Kaestchen
        // Minen haben.
        for (int i = 0; i < height; i++) {

            for (int j = 0; j < width; j++) {

                // Falls das Kaestchen eine Mine enthaelt wird -1 gespeichert.
                if (feld[i][j] == '*') {
                    feldNEU[i][j] = -1;
                }

                else {

                    int anzahlMinen = 0;

                    // Es muessen die acht Nachbarfelder betrachtet werden.
                    // Davor muss jedoch geschaut werden, ob es solch ein
                    // Nachbarfeld ueberhaupt gibt. Das Feld oben links hat z.B.
                    // keinen Nachbarn oben, keinen Nachbarn links und keinen
                    // Nachbarn oben links.

                    // Oben links
                    if (i > 0 && j > 0) {
                        if (feld[i - 1][j - 1] == '*') {
                            anzahlMinen++;
                        }
                    }

                    // Oben
                    if (i > 0) {
                        if (feld[i - 1][j] == '*') {
                            anzahlMinen++;
                        }
                    }

                    // Oben rechts
                    if (i > 0 && j < width - 1) {
                        if (feld[i - 1][j + 1] == '*') {
                            anzahlMinen++;
                        }
                    }

                    // Links
                    if (j > 0) {
                        if (feld[i][j - 1] == '*') {
                            anzahlMinen++;
                        }
                    }

                    // Rechts
                    if (j < width - 1) {
                        if (feld[i][j + 1] == '*') {
                            anzahlMinen++;
                        }
                    }

                    // Unten links
                    if (i < height - 1 && j > 0) {
                        if (feld[i + 1][j - 1] == '*') {
                            anzahlMinen++;
                        }
                    }

                    // Unten
                    if (i < height - 1) {
                        if (feld[i + 1][j] == '*') {
                            anzahlMinen++;
                        }
                    }

                    // Unten rechts
                    if (i < height - 1 && j < width - 1) {
                        if (feld[i + 1][j + 1] == '*') {
                            anzahlMinen++;
                        }
                    }

                    feldNEU[i][j] = anzahlMinen;
                }

            }

        }

        int summeAllerZahlen = 0;

        // Die Summe der Zahlen berechnen.
        for (int i = 0; i < height; i++) {
            for (int j = 0; j < height; j++) {
                if (feldNEU[i][j] > 0) {
                    summeAllerZahlen += feldNEU[i][j];
                }
            }
        }

        System.out.println(height + " " + width + " Field: " + summeAllerZahlen);

        for (int i = 0; i < height; i++) {

            // In der Ausgabe sollen beide Tabellen nebeneinander sein.
            // Dazu werden zwei for-Schleifen benoetigt.

            for (int j = 0; j < width; j++) {
                System.out.print(feld[i][j]);
            }

            // Zwei Leerzeichen
            System.out.print("  ");

            for (int j = 0; j < width; j++) {
                // Falls der Wert -1 ist soll ein Sternchen ausgegeben werden.
                // Anderenfalls soll der Wert ausgegeben werden.
                if (feldNEU[i][j] == -1) {
                    System.out.print("*");
                } else {
                    System.out.print(feldNEU[i][j]);
                }
            }

            // Zeilenumbruch
            System.out.print("\n");
        }

    }
}

Ausgabe:
Code:
3 5 Field: 11
**...  **100
.....  33200
.*...  1*100
 

btl1903

Mitglied
Dein Programm müsste demnach
Code:
*...
....
.*..
....
ausgeben aber derzeit gibt es folgendes aus:
Code:
....
.*..
....
Es fehlt also die erste Zeile. Ich helfe dir per PN.


meine Ausgabe lautet so:
Code:
Field:1
*...
....
.*..
....
Field:2
**...
.....
.*...
Field:3

die erste zeile fehlt nicht..
 

krgewb

Top Contributor
Wenn sie meinen Code ausführt kommt folgende Meldung:
Java:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
at de.hrw.Assignment1.main(Assignment1.java:72)
 

btl1903

Mitglied
der code funktioniert eigentlich, aber sobald ich einen längeren input benutze, bekomme ich eine ArrayIndexOutOfBoundsException. Der input muss doch beliebig sein also, darf ich zum beispiel auch so ein input haben, oder:
Code:
*.*...*
.*...*.
.*.*..*
..*..*.
*.*.*..
*.*...*
*.*.*..
*.*...*
 

btl1903

Mitglied
eigentlich müssen input und output so aussehen:
Code:
input:        output:

4 4            Field: 1
*...            *100
....             2210
.*..            1*10
....             1110
3 5            Field: 2 
**...          **100
.....            33200
.*...           1*100
0 0            22           // wenn 0x0, dann soll die Summe aller Zahlen ausgegeben werden

also soll im input schon stehen wie groß mein array sein soll.
 

thet1983

Top Contributor
Code:
// input.txt
*.*...*
.*...*.
.*.*..*
..*..*.
*.*.*..
*.*...*
*.*.*..
*.*...*

Code:
// output
8 7 Field: 103
*.*...*   *3*112*
.*...*.    3*422*3
.*.*..*   2*4*33*
..*..*.    24*43*2
*.*.*..   *5*4*32
*.*...*   *6*523*
*.*.*..   *6*4*32
*.*...*   *4*312*

was ist daran falsch?
 

btl1903

Mitglied
Beispiel input.txt:
Code:
4 4
*.*.
.*..
.*.*
..*.
3 5
**...          
.....          
.*...         
0 0

output:
Code:
Field: 1
*100
2210
1*10
1110
Field: 2
**100
33200
1*100
22   //Summe aller Zahlen

der input muss eigentlich anders sein!
 

btl1903

Mitglied
also ich habe folgenden input:
Code:
4 4
*.*.
.*..
.*.*
*.*.
3 5
**...        
.....        
.*...       
0 0

Das programm soll wissen, dass ich ein 4x4 und ein 3x5 feld habe, danach die zeichen lesen und die Zahlen ausgeben. Wenn ich ein 0x0 feld habe, soll die summe aller zahlen ausgegeben werden.

mein output sollte dann so aussehen:

Code:
Field: 1
*100
2210
1*10
1110
Field: 2
**100
33200
1*100
22   //Summe aller Zahlen

also ich sollte ein zähler für die felder haben, und am ende die summe aller zahlen.

ich habe jetzt dein Code bisschen umgeformt, so dass ich den Feldzähler habe. Aber es funktioniert trotzdem irgendwas nicht. Das programm kann ab der zweiten Zeile die Zeichen * und . nicht lesen denk ich.
 

btl1903

Mitglied
ich bekomme diese Ausgabe:
Code:
Field:1
Field:2
Field:3
FEHLER. Die Anzahl der Zeilen ist 0.

Statt Field: 3 muss eigentlich die summe der zahlen stehen, aber das muss ich noch ändern.

Wenn ich ein paar sachen ändere, bekomme ich eine ArrayIndexOutOfBoundsException
 

krgewb

Top Contributor
So. Jetzt sollte alles funktionieren.

input.txt:
Code:
4 4
*...
....
.*..
....
3 5
**...
.....
.*...
0 0

Assignment1:
Java:
import java.io.*;
import java.util.ArrayList;

public interface Assignment1 {
    public long minesweep(File inputfile);

    public static void main(String[] args) throws FileNotFoundException {

        BufferedReader br;

        int summeAllerZahlen = 0;

        ArrayList<String> dateiInhalt = new ArrayList<String>();

        ArrayList<char[][]> arrays = new ArrayList<char[][]>();

        // Fuer die Arrays mit den neuen Feldern (fuer Output) wird int als
        // Datentyp verwendet. Alternativ kann mit einem char-Array und
        // ASCII-Tabelle (
        // http://www.chip.de/ii/1/2/5/4/9/5/8/0/ascii-93c823e7009f26b0.png )
        // gearbeitet werden.
        ArrayList<int[][]> arraysNEU = new ArrayList<int[][]>();

        // Die Datei wird eingelesen und der komplette Inhalt wird in einer
        // ArrayList gespeichert.

        try {
            br = new BufferedReader(new FileReader("input.txt"));
            try {
                String x;

                // Die Schleife wird fuer alle Zeilen in der Datei
                // durchlaufen.
                while ((x = br.readLine()) != null) {
                    // trim entfernt fuehrende und nachfolgende Leerzeichen
                    x = x.trim();
                    if (x.equals("") == false) {
                        dateiInhalt.add(x);
                    }
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        } catch (FileNotFoundException ex) {
            ex.printStackTrace();
        }

        // Nun wird die ArrayList mit dem Dateiinhalt durchgeguckt und geschaut,
        // ob die einzelnen Zeilen Ziffern enthalten. Aufgrund der Informationen
        // werden arrays erstellt (aber noch nicht befuellt) und zu
        // einer ArrayList namens arrays hinzugefuegt.

        for (int i = 0; i < dateiInhalt.size(); i++) {

            String einzelneZeile = dateiInhalt.get(i);

            if (StringEnthaeltMindestensEineZiffer(einzelneZeile) == true) {

                // In solch einer Zeile sind ja zwei Werte hinterlegt. Diese
                // sind durch ein Leerzeichen getrennt. Mithilfe der
                // split-Methode koennen die Werte herausgepickt werden.
                String[] hoeheUndBreite = einzelneZeile.split(" ");

                int height = Integer.parseInt(hoeheUndBreite[0]);
                int width = Integer.parseInt(hoeheUndBreite[1]);

                if (height > 0 && width > 0) {
                    char[][] feld = new char[height][width];
                    arrays.add(feld);

                    int[][] feldNEU = new int[height][width];
                    arraysNEU.add(feldNEU);
                }

            }
        }

        int wievielteZeileMitAngabenZuHoeheUndBreite = 0;

        // Nun wird die ArrayList nochmals durchgeguckt und es werden die arrays
        // befuellt.
        for (int i = 0; i < dateiInhalt.size(); i++) {

            String einzelneZeile = dateiInhalt.get(i);

            if (StringEnthaeltMindestensEineZiffer(einzelneZeile) == true) {

                wievielteZeileMitAngabenZuHoeheUndBreite++;

                if (wievielteZeileMitAngabenZuHoeheUndBreite > arrays.size()) {
                    continue;
                }

                char[][] array = arrays.get(wievielteZeileMitAngabenZuHoeheUndBreite - 1);

                int height = array.length;
                int width = array[0].length;

                if (height > 0 && width > 0) {

                    for (int k = 1; k < height + 1; k++) {

                        String ganzeZeileMitPunktenUndSternen = dateiInhalt.get(i + k);

                        for (int m = 0; m < width; m++) {
                            array[k - 1][m] = ganzeZeileMitPunktenUndSternen.charAt(m);
                        }
                    }
                }

            }

        }

        for (int p = 0; p < arrays.size(); p++) {

            char[][] aktuellesArray = arrays.get(p);

            int height = aktuellesArray.length;
            int width = aktuellesArray[0].length;

            int[][] aktuellesArrayNEU = arraysNEU.get(p);

            // Nun wird fuer jedes Kaestchen geschaut, wieviele
            // Nachbar-Kaestchen Minen haben.
            for (int i = 0; i < height; i++) {

                for (int j = 0; j < width; j++) {

                    // Falls das Kaestchen eine Mine enthaelt wird -1
                    // gespeichert.
                    if (aktuellesArray[i][j] == '*') {
                        aktuellesArrayNEU[i][j] = -1;
                    }

                    else {

                        int anzahlMinen = 0;

                        // Es muessen die acht Nachbarfelder betrachtet werden.
                        // Davor muss jedoch geschaut werden, ob es solch ein
                        // Nachbarfeld ueberhaupt gibt. Das Feld oben links hat
                        // z.B. keinen Nachbarn oben, keinen Nachbarn links und
                        // keinen Nachbarn oben links.

                        // Oben links
                        if (i > 0 && j > 0) {
                            if (aktuellesArray[i - 1][j - 1] == '*') {
                                anzahlMinen++;
                            }
                        }

                        // Oben
                        if (i > 0) {
                            if (aktuellesArray[i - 1][j] == '*') {
                                anzahlMinen++;
                            }
                        }

                        // Oben rechts
                        if (i > 0 && j < width - 1) {
                            if (aktuellesArray[i - 1][j + 1] == '*') {
                                anzahlMinen++;
                            }
                        }

                        // Links
                        if (j > 0) {
                            if (aktuellesArray[i][j - 1] == '*') {
                                anzahlMinen++;
                            }
                        }

                        // Rechts
                        if (j < width - 1) {
                            if (aktuellesArray[i][j + 1] == '*') {
                                anzahlMinen++;
                            }
                        }

                        // Unten links
                        if (i < height - 1 && j > 0) {
                            if (aktuellesArray[i + 1][j - 1] == '*') {
                                anzahlMinen++;
                            }
                        }

                        // Unten
                        if (i < height - 1) {
                            if (aktuellesArray[i + 1][j] == '*') {
                                anzahlMinen++;
                            }
                        }

                        // Unten rechts
                        if (i < height - 1 && j < width - 1) {
                            if (aktuellesArray[i + 1][j + 1] == '*') {
                                anzahlMinen++;
                            }
                        }

                        aktuellesArrayNEU[i][j] = anzahlMinen;
                    }

                }

            }

            int summeAllerZahlenEinesArrays = 0;

            // Die Summe der Zahlen berechnen.
            for (int i = 0; i < height; i++) {
                for (int j = 0; j < width; j++) {
                    if (aktuellesArrayNEU[i][j] > 0) {
                        summeAllerZahlenEinesArrays += aktuellesArrayNEU[i][j];
                    }
                }
            }

            summeAllerZahlen += summeAllerZahlenEinesArrays;

            System.out.print(HoleDieSoundsovielteZeileMitAngabenZuHoeheUndBreite(dateiInhalt, p + 1));
            System.out.print("  Field: " + summeAllerZahlenEinesArrays + "\n");

            for (int i = 0; i < height; i++) {

                // In der Ausgabe sollen beide Tabellen nebeneinander sein. Dazu
                // werden zwei for-Schleifen benoetigt.

                for (int j = 0; j < width; j++) {
                    System.out.print(aktuellesArray[i][j]);
                }

                // Zwei Leerzeichen
                System.out.print("  ");

                for (int j = 0; j < width; j++) {
                    // Falls der Wert -1 ist soll ein Sternchen ausgegeben
                    // werden. Anderenfalls soll der Wert ausgegeben werden.
                    if (aktuellesArrayNEU[i][j] == -1) {
                        System.out.print("*");
                    } else {
                        System.out.print(aktuellesArrayNEU[i][j]);
                    }
                }

                // Zeilenumbruch
                System.out.print("\n");
            }

        }

        for (int i = 0; i < dateiInhalt.size(); i++) {
            if (dateiInhalt.get(i).equals("0 0")) {
                System.out.print(dateiInhalt.get(i) + "  " + summeAllerZahlen);
            }
        }

    }

    public static boolean StringEnthaeltMindestensEineZiffer(String einzelneZeile) {

        for (int i = 0; i < einzelneZeile.length(); i++) {

            Character c = einzelneZeile.charAt(i);

            // Sobald eine Ziffer gefunden worden ist wird true zurueckgegeben.
            if (Character.isDigit(c)) {
                return true;
            }
        }

        return false;
    }

    public static String HoleDieSoundsovielteZeileMitAngabenZuHoeheUndBreite(ArrayList<String> dieArrayList, int n) {

        int wievielteZeileMitAngabenZuHoeheUndBreite = 0;

        for (int i = 0; i < dieArrayList.size(); i++) {

            if (StringEnthaeltMindestensEineZiffer(dieArrayList.get(i))) {
                wievielteZeileMitAngabenZuHoeheUndBreite++;
            }

            if (n == wievielteZeileMitAngabenZuHoeheUndBreite) {
                return dieArrayList.get(i);
            }
        }

        return null;
    }
}

Ausgabe:
Code:
4 4  Field: 11
*...  *100
....  2210
.*..  1*10
....  1110
3 5  Field: 11
**...  **100
.....  33200
.*...  1*100
0 0  22
 

krgewb

Top Contributor
Achso! Entschuldige vielmals. Ich schaue es mir heute an.

Edit: Ich habe es mir angeschaut. Die Zeile muss wie folgt lauten:
Java:
System.out.print("  Field: " + (p + 1) + "\n");
 
Zuletzt bearbeitet:

Neue Themen


Oben