Erste Schritte Schiffe versenken

d4nue44

Mitglied
Hey leute,
ich bin beim Java programmieren ein blutiger Anfänger ....
Ich möchte Schiffe versenken programmieren und habe mit müh und not sowie mit viel Hilfe das Grundgerüst für Schiffe versenken programmiert.
Es soll in der Konsole gespielt werden.
Bissher wurden die Schiffe im Quelltext selbst gesetzt.
Jetzt möchte ich, dass das Programm mich abfragt wo ich welche Schiffe haben möchte.
Ich habe echt 0 Plan wie man sowas anstellt ...

Vieleicht kann mir das jemand an meinem Quellcode erläutern.
Vielen Dank.
 

d4nue44

Mitglied
Java:
import java.util.Scanner;

public class SchiffeVersenken {

    private static char[][] firstplayer = {
        {'#', '#', '#', '#', '.', '.', '.', '.', '.', '#', },
        {'.', '.', '.', '.', '.', '#', '#', '.', '.', '#', },
        {'.', '.', '#', '.', '#', '#', '#', '.', '.', '.', },
        {'.', '.', '#', '.', '.', '.', '.', '#', '#', '#', },
        {'.', '.', '#', '.', '.', '#', '.', '.', '.', '.', },
        {'.', '.', '#', '.', '.', '#', '.', '.', '.', '.', },
        {'.', '.', '#', '.', '.', '#', '.', '.', '#', '.', },
        {'#', '.', '.', '.', '.', '.', '.', '.', '#', '.', },
        {'#', '.', '.', '.', '.', '.', '.', '.', '.', '.', },
        {'.', '.', '.', '.', '#', '#', '#', '#', '.', '.', } };

    private static char[][] secondplayer = {
        {'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', },
        {'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', },
        {'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', },
        {'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', },
        {'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', },
        {'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', },
        {'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', },
        {'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', },
        {'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', },
        {'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', } };

    private static Scanner s = new Scanner(System.in);

    public static void main(String[] args) {
        System.out.println("\n \n ********************************");
        System.out.println("\n We welcome you to Battleship");
        System.out.println("\n ******************************\n");

        String modus;
        System.out.println("Please type in your name:");
        String player1 = s.nextLine();
        System.out.println("Please type in your enemies name:");
        String player2 = s.nextLine();
          
        System.out.println("If you are ready choose heads or tails and press 'enter' to continue.");
        modus = s.nextLine();
          
        if ("".equals(modus)) {
            SchiffeVersenken.cointoss();
        } else {
            return;
        }
        modus = s.nextLine();

        while (true) {
            System.out.println("\n Field of " + player1 + "\n");
            SchiffeVersenken.print(SchiffeVersenken.firstplayer);
            System.out.println("\n ************");
            System.out.println("\n Field of " + player2 + "\n");
            SchiffeVersenken.print(SchiffeVersenken.secondplayer);

            System.out.println("\n Please type in (attack,defend,exit) : ");
            modus = s.nextLine();

            if ("attack".equals(modus)) {
                SchiffeVersenken.attack();
            }
            if ("defend".equals(modus)) {
                SchiffeVersenken.defend();
            }
            if ("exit".equals(modus)) {
                break;
            }
        }
        System.out.println("\n Game finished");
    }

    public static void print(char[][] gitter) {
        System.out.println(" 0123456789");
        for (int r = 0; r < gitter.length; r++) {
            System.out.print("ABCDEFGHIJ".charAt(r));
            for (int c = 0; c < gitter.length;  c++) {
                System.out.print(gitter[r][c]);
            }
            System.out.println("");
        }
    }

    public static void attack() {

        Scanner s = new Scanner(System.in);

        String input;
        char zeile;     
        System.out.println("Please type in row: ");
        input = s.next();
        zeile = input.charAt(0);

        String input1;
        char spalte;
        System.out.println("Please type in column: ");
        input1 = s.next();
        spalte = input1.charAt(0);

      
        int row;
        row = (int)zeile;
      
        int column;
        column = (int)spalte;



        boolean hit;
        System.out.println("Did the attack hit? (type in true or false):");
        hit = s.nextBoolean();

      

        if (hit) {
            secondplayer[row][column] = 'X';
        } else {
            secondplayer[row][column] = 'o';
        }

    }

    public static void defend() {
        Scanner s = new Scanner(System.in);

        String input2;
        char row;
        System.out.println("Please type in row: ");
        input2 = s.next();
        row = input2.charAt(0);

        String input3;
        char column;
        System.out.println("Please type in column: ");
        input3 = s.next();
        column = input3.charAt(0);


        if (firstplayer[row][column] == '#') {
            firstplayer[row][column] = 'X';
        } else {
            firstplayer[row][column] = 'o';
        }

    }

    public static void cointoss() {
        Scanner m = new Scanner(System.in);
      
      
        double zufallszahl = Math.random();
      
      
        if (zufallszahl <= 0.49) {
            System.out.println("\n Heads \n");
        } else {
            System.out.println("\n Tails \n");
        }

    }
}
 
Zuletzt bearbeitet von einem Moderator:

JStein52

Top Contributor
du initialisierst deine arrays mit '.' Und danach fragt du den Spieler nach den Koordinaten wo er ein Schiff hinhaben möchte, ob das Schiff waagerecht oder senkrecht sein soll und wie gross.
Du kannst dann ja Prüfungen einbauen dass er von jeder Sorte nur soviele Schiffe anlegt wie du möchtest.
Und die eingegeben Koordinaten rechnest du in die entsprechenden Indizes um. Und das ganze machst du damit es übersichtlich bleibt in einer eigenen Methode.
 
K

kneitzel

Gast
Hallo,

das ist ja schon recht schön geworden.

Ehe ich auf das dynamische Setzen der Schiffe eingehe möchte ich dir ein paar allgemeine Dinge Sagen, die mir so aufgefallen sind:
- Du bist in einer Art "Scriptmodus". Main wird gestartet und dann läuft alles etwas scriptartig. Alles ist static und damit es es wie ein Script, welches ab dem Einstiegspunkt einfach abläuft. Das würde ich etwas umändern. In der main Methode werden eigentlich immer nur ein paar Objekte erzeugt und dann die Kontrolle an diese abgegeben.
- Ein weiterer Schritt, der auch etwas mit dem ersten zusammen hängt ist der Einstieg in die Objektorientierte Entwicklung. hier wäre mein Vorschlag, dass Du ein paar erste Klassen erzeugst.

Möglicher Aufbau könnte sein:
a) Erst einmal hast Du eine Klasse Schiffe versenken. Du könntest Deine statischen Dinge bis auf Main() erst einmal in einem ersten Schritt das static wegnehmen. main benennst du einfach um in start oder so und machst dann eine neue main Funktion, die halt dann etwas macht wie
Code:
SchiffeVersenken spiel = new SchiffeVersenken();
spiel.start();

Dann hast du deine erste Objektinstanz - dein SchiffeVersenken Spiel.

Ein weiterer Schritt wäre, dass Du eine Klasse "Spielbrett" (Evtl. fällt Dir noch ein besserer Name an. See oder Meer oder was auch immer.) anlegst. Diese Klasse bekommt dann erst einmal Dein zweidimensionales Array aber bitte als "private" und nicht als public, so dass da von Aussen nicht zugegriffen werden kann,. Und deine firstplayer und secondplayer werden dann vom Typ Spielbrett.
Wenn Du dies gemacht hast, dann funktioniert erst einmal nichts mehr. Alle Zugriffe sind jetzt falsch und bringen Compilier-Fehler.
Das Array wird dann auch erst einmal leer initialisiert - also keine Schiffe.
Jetzt musst Du alle Fehler durchgehen und schauen, was wird denn da genau gemacht?
Statt den genauen Zugriffen baust Du nun Funktionen in die Klasse Spielbrett, die die eigentliche Aktion beschreiben.
So wären Funktionen wie boolean schiessenAufKoordinate(int x, int y) denkbar. Diese Funktion prüft, ob auf der Koordinate ein Schiff ist oder nicht, setzt das Zeichen um, das angibt, dass da schon hingeschossen wurde und gibt dann zurück, ob es ein Treffer war (true: Treffer, false: Wasser)
Daqs wäre dann schon ein erster Anfang.
Dann wirst Du mit der Umstellung durch sein und es bleibt das Problem, dass keine Schiffe vorhanden sind. Hier brauchen wir noch eine Erweiterung.
Hier wäre eine Funktion addShip oder hinzufuegenSchiff oder schiffHinzufuegen oder wie auch immer denkbar. Parameter sind dann evtl. Koordinaten, Richtung (z.B. Norden 1, NordOst: 2, Ost: 3, ...) und Größe. Diese Funktion prüft dann, ob das Schiff gesetzt werden kann (Platz vorhanden? Keine Plätze bereits vergeben?) und setzt dann das Schiff. Um Fehler abzufangen kann man hier auch ein boolean zurück geben so dass man true: erfolgreich, false: nicht erfolgreich zurückgeben könnte.

Dann wäre der nächste Schritt erst einmal, dass man die Schiffe am Anfang setzt. Im ersten Schritt evtl. einfach die existierenden Schiffe über die eben erstellte Funktion setzen und im Anschluss kannst Du dann die Applikation wieder testen. Es sollte hier alles so funktionieren wie zuvor.

An der Stelle kann dann Dein eigenes Anliegen endlich umgesetzt werden. Du kannst einmal definieren, was für Schiffe es geben soll. Das kann z.B. ein Array aus Integern sein wobei jede Zahl ein Schiff angibt. {2, 2, 3, 3, 4, 5, 6} wäre dann zwei Zweier, zwei Dreier und dann jeweils ein Vierer, Fünfer und Sechser Schiff. Dann gibt es im Spiel eine Funktion, welche "schiffeSetzen" heisst. Diese hat eine schleife, welche durch diese Schiffsvorgabe geht und dann den Nutzer bittet, x, y und Richtung einzugeben. Dann wird das Schiff gesetzt. Sollte das nicht geklappt haben, wird das gleiche Schiff erneut angefragt. Hat es geklappt, dann kommt das nächste Schiff. Die Schleife endet, wenn alle Schiffe gesetzt sind, oder der Benutzer abgebrochen hat.

So könnte die weitere Entwicklung des Spiels ablaufen.

Viele Grüße,

Konrad
 

d4nue44

Mitglied
Erstmal vielen Dank für die zahlreichen Infos.

Grade bin ich auf ein anderes Problem gestoßen.

Nach der Eingabe der Zeile und Spalte bzw. Row und Column und nach Abfrage ob es ein Treffer war kommt ein error arrayindexoutofboundsexpection ...

wie könnte ich das problem beheben ?

Java:
public static void attack() {

        Scanner s = new Scanner(System.in);
        String input;
        char row;     
        System.out.println("Please type in row: ");
        input = s.next();
        row = input.charAt(0);

        String alb[] = {"A", "B", "C"};

        String input1;
        char column;
        System.out.println("Please type in column: ");
        input1 = s.next();
        column = input1.charAt(0);

        String hit;
        System.out.println("Do you hit? (Y/N)");
        hit = s.next();

        int r;
        int t;
        t=65;
        r = row - t;

        int c;   
        c=column;

        while (hit.equals("Y")){
            secondplayer[r][c] = 'X';
            print(secondplayer);
            System.out.println("Next one!");
            System.out.println("row?");
            input = s.next();
            System.out.println("column?");
            input1 = s.next();
            System.out.println("Do you hit? (Y/N)");
            hit = s.next();
        }
      

        if (hit.equals("N")) {
            secondplayer[r][c] = 'o';
            System.out.println("fail!");
            print(secondplayer);
        } else {
            System.out.println("wrong ");
        }

    }
 
Zuletzt bearbeitet von einem Moderator:

Joose

Top Contributor
Weil du auf auf "seconplayer[r][c]" mit Indexen zugreifst die es nicht gibt.
Für "r" berechnest du davor "row-t" -> "row-65" bist du dir sicher das das so stimmt?
Verwende entweder den Debugger deiner IDE oder Konsolenausgaben um herauszufinden mit welchen falschen Werten du auf das Array zugreifst.
 

JStein52

Top Contributor
Naja ganz falsch scheint es mir nicht. 65 ist 'A' ! Aber ist sehr fehleranfällig. Wehe man gibt was falsches ein ! Ich würde mal mindestens noch ein paar Prüfungen einbauen damit da nichts passiert.
 

Joose

Top Contributor
Ah das ergibt natürlich Sinn ;)
Naja leider sind die Variablennamen nicht ganz aussagekräftig daher ist mir der Gedanke gar nicht gekommen.
 

d4nue44

Mitglied
Manchmal sieht man den Wald vor lauter Bäumen nicht ;)

Ich möchte jetzt eine Abfrage machen, möchte aber nur das Zahlenwerte von 0-9 eingegeben werden dürfen. Also die Eingabe von Buchstaben soll abgefangen werden und eine Fehlermeldung soll erscheinen.
Wie stell ich das mit den Buchstaben am besten an?
Dazu mein quelltext:
Java:
public static int questColumn(){
        Scanner s = new Scanner(System.in);
        int column;
        while (true){
            System.out.println("Please type in column");
            column = s.nextInt();
            if (column > 9 || column < 0){
                System.out.println("Incorrect input!");
            } else{
                break;
            }
        }
        return column;
    }
 

JStein52

Top Contributor
Wenn du da nun Buchstaben eingibst wirst du bei s.nextInt() eine "InputMismatchException"- Exception kriegen, die könntest du z.B. abfangen und eine Fehlermeldung ausgeben so wie du sie möchtest.
 

Ähnliche Java Themen

Neue Themen


Oben