Anfängerfrage zu meinem Programm.

Servus miteinander,
Ich arbeite derzeit das Buch „Java ist auch eine Insel“ durch und habe nun das erste Projekt aus dem Buch in Angriff genommen. Programmiert sollte eine Art Snake in der CMD werden. Bis jetzt funktioniert das Programm auch, wie es soll. Die Aufgaben, die ich hinzufügen sollte, waren folgende:
1. Eine zweite Schlange hinzufügen.
2. Einen zweiten Goldtopf hinzufügen.
3. Der Spieler darf 5 Züge tätigen, bevor die Schlangen sich anfangen zu bewegen.
4. Der Spieler und die anderen Objekte(Npcs) sollen auf zufälligen Koordinaten spawnen.
5. Den Code noch in verschiedene Methoden aufteilen. Diese Aufgabe ist aber nur für fortgeschrittene Personen. Ich hab’s auch leider nicht hinbekommen :/ was nicht ist, kann noch werden. ;)

Folgende Kapitel habe ich bereits im Buch durch:
Java ist auch eine Sprache, Imperative Sprachkonzepte und Klassen und Objekte.

Meine Frage an euch: Was denkt ihr von dem Aufbau? Oder habe ich mir etwas angeeignet, was ich schnell wieder stoppen sollte? Damit meine ich natürlich den Aufbau, ob’s leserlich ist, Kommentare etc.

Ich danke euch für eure Zeit und Unterstützung! Sollte alles entsprechend für einen Anfänger gut sein, werde ich mich an die nächsten Kapitel im Buch wagen. freu =)


Java:
import java.awt.Point;
import java.util.Scanner;

// DIES IST EIN ANFÄNGERPROJEKT AUS DEM BUCH "JAVA IST AUCH EINE INSEL". BITTE HABT VERSTÄNDNIS FÜR FEHLER!^^
// FALLS IHR ANFÄNGERFEHLER ERKENNT, DIE MAN SICH ABGEWÖHNEN SOLLTE, BITTE IN DIE KOMMENTARE SCHREIBEN :) DANKE!

public class Main {

    // Die verschiedenen Instanzvariablen für die Nutzung verschiedener Methoden.

    // Player(s)
    Point player = new Point(randomX(), randomY());

    // NPCs
    Point snake = new Point(randomX(), randomY());
    Point snake2 = new Point(randomX(), randomY());

    // Objects
    Point gold = new Point(randomX(), randomY());
    Point gold2 = new Point(randomX(), randomY());
    Point door = new Point(randomX(), randomY());

    Point teleport1 = new Point(randomX(), randomY());
    Point teleport2 = new Point(randomX(), randomY());
    Point teleport3 = new Point(randomX(), randomY());
    Point teleport4 = new Point(randomX(), randomY());

    int counter = 0; // Ein Zähler zum Zählen der "Züge", die der Spieler bis zum Sieg oder der
                        // Niederlage benötigte.

    boolean hatGold = false; // Sollte der Spieler einen Goldtopf einsammeln, wird der Wert auf True gesetzt
                                              // wodurch der Spieler die Berechtigung erhält, die Tür zum Sieg zu nutzen.

    public static void main(String[] args) {
        Main main = new Main();

        main.basicGame();
    }

    // Erstellt eine zufällige Nummer zwischen 1 und 10 der Y-Koordinate.
    public int randomY() {
        int y = (int) (Math.random() * 10);
        return y;
    }

    // Erstellt eine zufällige Zahl zwischen 1 und 40 der X-Koordinate.
    public int randomX() {
        int x = (int) (Math.random() * 40);
        return x;
    }

    // Die eigentliche Spielmechanik beginnt mit dieser Methode.
    public void basicGame() {
        Main main = new Main();

        while (true) {
            
            /* Die 2 For-Schleifen zum Aufbau des „Spielfelds“. Sollte der Point 'p' auf
             *  eine der Koordinaten von den Instanzvariablen treffen
             *  wird ein spezifisches Zeichen anstelle des Punktes auf dem Spielfeld ausgegeben/generiert.
            */
            
            for (int y = 0; y < 10; y++) {
                for (int x = 0; x < 40; x++) {
                    Point p = new Point(x, y);
                    if (main.player.equals(p))
                        System.out.print('&');
                    else if (main.snake.equals(p))
                        System.out.print('S');
                    else if (main.teleport1.equals(p))
                        System.out.print('T');
                    else if (main.teleport2.equals(p))
                        System.out.print('T');
                    else if (main.teleport3.equals(p))
                        System.out.print('T');
                    else if (main.teleport4.equals(p))
                        System.out.print('T');
                    else if (main.gold.equals(p))
                        System.out.print('$');
                    else if (main.door.equals(p))
                        System.out.print('#');
                    else if (main.snake2.equals(p))
                        System.out.print('S');
                    else if (main.gold2.equals(p))
                        System.out.print('$');
                    else
                        System.out.print(".");
                }
                System.out.println();

            // Die Spielereingabe zur Bewegung des Spielecharakters via Switchcase.
            }
            switch (new Scanner(System.in).next()) {
            case "w":
                main.player.y = Math.max(0, main.player.y - 1);
                break;
            case "s":
                main.player.y = Math.min(9, main.player.y + 1);
                break;
            case "a":
                main.player.x = Math.max(0, main.player.x - 1);
                break;
            case "d":
                main.player.x = Math.min(39, main.player.x + 1);
                break;
            }

            /* Fragt ab, ob der Spieler und die Schlange(n) sich auf den gleichen Koordinaten befinden.
            * Falls es der Fall sein, sollte wird der Spieler gebissen und verliert die Runde bzw. das Spiel.
            */
            if (main.player.equals(main.snake) || main.player.equals(main.snake2)) {
                System.out.println("Die Schlange hat dich gebissen! Das Spiel ist verloren...");
                System.out.println("Du hast nach " + main.counter + " Zügen verloren.");
                return;
            }

            // Sollte der Spieler das Gold eingesammelt haben und auf der Coordinate der Tür
            // stehen, gewinnt der Spieler.
            if (main.hatGold && main.player.equals(main.door)) {
                System.out.println("Du hast diese Runde gewonnen! Benötigte Züge: " + main.counter + ".");
                return;
            }

            // Abfrage, ob der Spieler auf einem der zwei Koordinate für die Goldtöpfe steht.
            // Falls das der Fall sein sollte, hat der Spieler das Recht, die Tür zu nutzen.
            // Der spezifische Goldtopf wird entfernt.
            if (main.player.equals(main.gold)) {
                main.hatGold = true;
                main.gold.move(-1, -1);
                System.out.println("Du hast den Topf voller Gold gefunden! Ab zur Tür!");
                continue;
            } else if (main.player.equals(main.gold2)) {
                main.hatGold = true;
                main.gold2.move(-2, -2);
                System.out.println("Du hast den Topf voller Gold gefunden! Ab zur Tür!");
                continue;
            }

            // Eine kleine Spielerei, die den Spieler zu zufälligen Koordinaten teleportiert.
            if (main.player.equals(main.teleport1)) {
                main.player.setLocation(main.randomX(), main.randomY());
                System.out.println("Du wurdest teleportiert!");
            } else if (main.player.equals(main.teleport2)) {
                main.player.setLocation(main.randomX(), main.randomY());
                System.out.println("Du wurdest teleportiert!");
            } else if (main.player.equals(main.teleport3)) {
                main.player.setLocation(main.randomX(), main.randomY());
                System.out.println("Du wurdest teleportiert!");
            } else if (main.player.equals(main.teleport4)) {
                main.player.setLocation(main.randomX(), main.randomY());
                System.out.println("Du wurdest teleportiert!");
            }

            // Der Zähler, um die Züge des Spielers zu zählen. Wird pro Durchlauf um 1 erhöht.
            main.counter++;

            // Die Abfrage der beiden Schlangen und ihre Bewegungen basierend auf die X und
            // Y Coordianten des Spielers.
            if (main.counter >= 5) {
                if (main.player.x < main.snake.x) {
                    main.snake.x -= 1;
                    if (main.player.x < main.snake2.x) {
                        main.snake2.x -= 1;
                    } else if (main.player.x > main.snake2.x) {
                        main.snake2.x += 1;
                    }
                } else if (main.player.x > main.snake.x) {
                    main.snake.x += 1;
                }

                if (main.player.y < main.snake.y) {
                    main.snake.y -= 1;
                    if (main.player.y < main.snake2.y) {
                        main.snake2.y -= 1;
                    } else if (main.player.y > main.snake2.y) {
                        main.snake2.y += 1;
                    }
                } else if (main.player.y > main.snake.y) {
                    main.snake.y += 1;
                }
            }
        }
    }
}
 

KonradN

Super-Moderator
Mitarbeiter
Was mir an dem Code auffällt:
Java:
    public void basicGame() {
        Main main = new Main();

basicGame ist eine Methode der Instanz. In der Methode hast Du also eine Instanz von Main, mit der du arbeiten kannst. Es gibt somit keine Notwendigkeit eine zweite Instanz anzulegen. Dieses Main main = new Main(); kann also ersatzlos gestrichen werden.

Im Zuge dessen, musst Du alle Zugriffe darauf heraus nehmen, also wenn Du etwas hast wie:
main.snake.y -= 1; dann wird daraus ein this.snake.y -= 1; oder einfach snake.y -= 1; (das this. ist optional und würde nur dann gebraucht, wenn das Element verdeckt wäre.)

Edit: Und ganz vergessen: Das Schreiben von Methoden solltest Du Dir auf jeden fall näher anschauen. Auch wenn es als fortgeschritten bezeichnet wurde ist das so existenziell - sauberen Code kann man kaum ohne Methoden schreiben!
 
Was mir an dem Code auffällt:
Java:
    public void basicGame() {
        Main main = new Main();

basicGame ist eine Methode der Instanz. In der Methode hast Du also eine Instanz von Main, mit der du arbeiten kannst. Es gibt somit keine Notwendigkeit eine zweite Instanz anzulegen. Dieses Main main = new Main(); kann also ersatzlos gestrichen werden.

Im Zuge dessen, musst Du alle Zugriffe darauf heraus nehmen, also wenn Du etwas hast wie:
main.snake.y -= 1; dann wird daraus ein this.snake.y -= 1; oder einfach snake.y -= 1; (das this. ist optional und würde nur dann gebraucht, wenn das Element verdeckt wäre.)

Edit: Und ganz vergessen: Das Schreiben von Methoden solltest Du Dir auf jeden fall näher anschauen. Auch wenn es als fortgeschritten bezeichnet wurde ist das so existenziell - sauberen Code kann man kaum ohne Methoden schreiben!
Vielen Dank für die schnelle Antwort! Das mit der Instanz Erstellung werde ich mir dann, wie auch die Methoden nochmals genauer anschauen. Ebenso das Schlüsselwort this.

Damit bedanke ich mich nochmals für das Aufzeigen meiner Fehler bzw. das mangelnde Wissen in den von ihnen aufgezählten Bereichen! Wenn sonst scheinbar alles okay ist, freut mich das schonmal sehr, da ich im RL niemanden kenne, der mir in Sachen IT weiterhelfen kann und ich mir jegliches Wissen selbst aneigne. ^^
 
Was mir an dem Code auffällt:
Java:
    public void basicGame() {
        Main main = new Main();

basicGame ist eine Methode der Instanz. In der Methode hast Du also eine Instanz von Main, mit der du arbeiten kannst. Es gibt somit keine Notwendigkeit eine zweite Instanz anzulegen. Dieses Main main = new Main(); kann also ersatzlos gestrichen werden.

Im Zuge dessen, musst Du alle Zugriffe darauf heraus nehmen, also wenn Du etwas hast wie:
main.snake.y -= 1; dann wird daraus ein this.snake.y -= 1; oder einfach snake.y -= 1; (das this. ist optional und würde nur dann gebraucht, wenn das Element verdeckt wäre.)

Edit: Und ganz vergessen: Das Schreiben von Methoden solltest Du Dir auf jeden fall näher anschauen. Auch wenn es als fortgeschritten bezeichnet wurde ist das so existenziell - sauberen Code kann man kaum ohne Methoden schreiben!
Guten Abend oder Morgen Konrad,
Wie sie sagten, habe ich mir das Kapitel der Methoden angesehen und etwas herumprobiert. Natürlich hätte ich es auch noch auf verschiedene Klassen aufteilen können, aber das habe ich mir gespart, da ich dieses Projekt nicht großartig weiter ausbauen werde, denke ich.

Sollte eine Antwort kommen, möchte ich mich schon einmal ganz herzlich für ihre Zeit bedanken!

Der aktuelle Code:

Java:
import java.awt.Point;
import java.util.Scanner;

public class Main {

    // Die verschiedenen Instanzvariablen für die Nutzung verschiedener Methoden.

    // Player
    Point player = new Point(randomX(), randomY());

    // NPCs
    Point snake = new Point(randomX(), randomY());
    Point snake2 = new Point(randomX(), randomY());

    // Objects
    Point gold = new Point(randomX(), randomY());
    Point gold2 = new Point(randomX(), randomY());
    Point door = new Point(randomX(), randomY());

    Point teleport1 = new Point(randomX(), randomY());
    Point teleport2 = new Point(randomX(), randomY());
    Point teleport3 = new Point(randomX(), randomY());
    Point teleport4 = new Point(randomX(), randomY());

    int counter = 0; // Ein Zähler zum zälen der "Züge" die der Spieler bis zum Sieg oder der
                        // Niederlage benötigte.

    boolean hatGold = false; // Sollte der Spieler einen Goldtopf einsammeln, wird der Wert auf True gesetzt
                                // wodurch der Spieler die Berechtigung erhält die Tür zum Sieg zu nutzen.

    public static void main(String[] args) {
        Main main = new Main();

        main.runningGame();
    }

    public void drawingMap() {
        while (true) {
            for (int y = 0; y < 10; y++) {
                for (int x = 0; x < 40; x++) {
                    Point p = new Point(x, y);
                    if (this.player.equals(p))
                        System.out.print('&');
                    else if (this.snake.equals(p))
                        System.out.print('S');
                    else if (this.teleport1.equals(p))
                        System.out.print('T');
                    else if (this.teleport2.equals(p))
                        System.out.print('T');
                    else if (this.teleport3.equals(p))
                        System.out.print('T');
                    else if (this.teleport4.equals(p))
                        System.out.print('T');
                    else if (this.gold.equals(p))
                        System.out.print('$');
                    else if (this.door.equals(p))
                        System.out.print('#');
                    else if (this.snake2.equals(p))
                        System.out.print('S');
                    else if (this.gold2.equals(p))
                        System.out.print('$');
                    else
                        System.out.print(".");
                }
                System.out.println();
            }
            break;
        }
    }

    public void movingPlayer() {
        // Die Spielereingabe zur Bewegung des Spielcharakters via Switchcase.

        switch (new Scanner(System.in).next()) {
        case "w":
            this.player.y = Math.max(0, this.player.y - 1);
            break;
        case "s":
            this.player.y = Math.min(9, this.player.y + 1);
            break;
        case "a":
            this.player.x = Math.max(0, this.player.x - 1);
            break;
        case "d":
            this.player.x = Math.min(39, this.player.x + 1);
            break;
        }
    }

    public void teleports() {
        // Eine kleine Spielerrei die den Spieler zu zufälligen Koordinaten teleportiert.

        if (this.player.equals(this.teleport1)) {
            this.player.setLocation(this.randomX(), this.randomY());
            System.out.println("Du wurdest teleportiert!");
        } else if (this.player.equals(this.teleport2)) {
            this.player.setLocation(this.randomX(), this.randomY());
            System.out.println("Du wurdest teleportiert!");
        } else if (this.player.equals(this.teleport3)) {
            this.player.setLocation(this.randomX(), this.randomY());
            System.out.println("Du wurdest teleportiert!");
        } else if (this.player.equals(this.teleport4)) {
            this.player.setLocation(this.randomX(), this.randomY());
            System.out.println("Du wurdest teleportiert!");
        }
    }

    public boolean playerStatus() {

        boolean playerStatus = false;

        /*
         * Fragt ab ob der Spieler und die Schlange(n) sich auf den gleichen Koordinaten
         * befinden. Falls es der Fall sein sollte wird der Spieler gebissen und
         * verliert die Runde bzw. das Spiel.
         */
        if (this.player.equals(this.snake) || this.player.equals(this.snake2)) {
            System.out.println("Die Schlange hat dich gebissen! Das Spiel ist verloren...");
            System.out.println("Du hast nach " + this.counter + " Zügen verloren.");
            playerStatus = true;
            return playerStatus;
        }

        // Sollte der Spieler das Gold eingesammelt haben und auf der Coordinate der Tür
        // stehen, gewinnt der Spieler.
        if (this.hatGold && this.player.equals(this.door)) {
            System.out.println("Du hast diese Runde gewonnen! benötigte Züge: " + this.counter + ".");
            playerStatus = true;
            return playerStatus;
        }

        // Abfrage ob der Spieler auf einem der zwei Coordinate für die Goldtöpfe steht.
        // Falls das der Fall sein sollte, hat der Spieler das recht die Tür zu nutzen.
        // Der spezifische Goldtopf wird entfernt.
        if (this.player.equals(this.gold)) {
            this.hatGold = true;
            this.gold.move(-1, -1);
            System.out.println("Du hast den Topf voller Gold gefunden! Ab zur Tür!");
            return playerStatus;

        } else if (this.player.equals(this.gold2)) {
            this.hatGold = true;
            this.gold2.move(-2, -2);
            System.out.println("Du hast den Topf voller Gold gefunden! Ab zur Tür!");
            return playerStatus;
        }

        return playerStatus;
    }

    public void snakes() {

        // Die Abfrage der beiden Schlangen und ihre Bewegungen basierend auf die X und
        // Y Koordianten des Spielers.

        if (this.counter >= 5) {
            if (this.player.x < this.snake.x) {
                this.snake.x -= 1;
                if (this.player.x < this.snake2.x) {
                    this.snake2.x -= 1;
                } else if (this.player.x > this.snake2.x) {
                    this.snake2.x += 1;
                }
            } else if (this.player.x > this.snake.x) {
                this.snake.x += 1;
            }

            if (this.player.y < this.snake.y) {
                this.snake.y -= 1;
                if (this.player.y < this.snake2.y) {
                    this.snake2.y -= 1;
                } else if (this.player.y > this.snake2.y) {
                    this.snake2.y += 1;
                }
            } else if (this.player.y > this.snake.y) {
                this.snake.y += 1;
            }
        }
    }

    // Erstellt eine zufällige Zahl zwischen 1 und 10 der Y-Koordinate.
    public int randomY() {
        int y = (int) (Math.random() * 10);
        return y;
    }

    // Erstellt eine zufällige Zahl zwischen 1 und 40 der X-Koordinate.
    public int randomX() {
        int x = (int) (Math.random() * 40);
        return x;
    }

    public void runningGame() {

        while (true) {

            drawingMap();

            movingPlayer();

            this.counter++;

            snakes();

            teleports();

            if (playerStatus() == true) {
                break;
            } else if (playerStatus() == false) {
                continue;
            }

        }
    }
}
 

KonradN

Super-Moderator
Mitarbeiter
Natürlich hätte ich es auch noch auf verschiedene Klassen aufteilen können, aber das habe ich mir gespart, da ich dieses Projekt nicht großartig weiter ausbauen werde, denke ich.
Die Aufteilung in Klassen wird erst wichtig, wenn Du auch anfängst objektorientiert zu arbeiten. Da bist du noch etwas am Anfang meine ich.

Ich baue da mal einfach ein fiktives Beispiel:
So wäre z.B. eine Klasse RandomPointGenerator denkbar. Der kann dann zufällige Punkte herausgeben.
Und da wäre dann eine mögliche Anforderung, dass keine Punkte doppelt vergeben werden. Der Generator muss sich also alle bereits generierten Punkte merken um dann immer zu prüfen, ob der neu generierte Punkt schon vergeben wurde.

Und dann macht es ggf. Sinn, davon mehrere Instanzen zu haben, weil die Anforderung ist:
  • Gold, Spieler und Tür dürfen nicht den gleichen Startpunkt haben
  • Schlangen können beliebig starten (Also auch auf Gold, Spieler und Tür - die ersten 5 Züge bewegt sich der Spieler und eine Kollision mit Schlangen am Startpunkt wird nicht geprüft) aber nicht aufeinander!

Das mag an den Haaren herbei gezogen sein, aber das macht den Ansatz etwas deutlicher- Du hast jetzt eine Klasse, die in sich etwas kapselt und eine gewisse Funktionalität hat. Und davon brauchst Du dann auch direkt mehrere Instanzen.

Aber noch einmal etwas zu dem Code:
Java:
            if (playerStatus() == true) {
                break;
            } else if (playerStatus() == false) {
                continue;
            }

playerStatus() gibt bereits ein boolean zurück. Da ist ein == true nicht notwendig. Das macht daraus ja ein true == true oder eben false == true.
Und das ist natürlich vom Ergebnis direkt ein true oder false. Es reicht also ein if (playerStatus()) aus.

Und bei einem if kommst Du in den else Zweig hinein, wenn das if nicht erfüllt ist. Wenn playerStatus() nicht true ist, dann ist doch klar, dass es false ist. Da ist also keine weitere Prüfung notwendig.

Damit hätten wir etwas wie:
Java:
            if (playerStatus()) {
                break;
            } else {
                continue;
            }

Nun können wir noch die Logik betrachten: Du bist in einer Schleife. Wenn playStatus wahr ist, dann verlässt Du die Schleife. Immer wenn Du sowas hast (der gradlinige Ablauf wird verlassen durch return, break, continue oder throw - ich hoffe ich habe nichts vergessen.) dann brauchst Du kein else Zweig!

Den kannst Du also wegnehmen und einfach die Befehle aus dem else Zweig so hin schreiben:
Java:
            if (playerStatus()) {
                break;
            }
            continue;

Und an dieser Stelle kann das continue auch direkt weg. Das ist am Ende des Blocks der Schleife und damit ist der Block vorbei. Ein einzelnes, unbedingtes continue macht keinen Sinn. Wenn danach noch Befehle kämen, wäre der Code nicht erreichbar:
Java:
while (....) {
    // ...
    
    continue;
    
    // Code hier würde nie ausgeführt!
}

Und dann kommen wir bei der While-Schleife zu einem weiteren Punkt. Derzeit hast Du:
Java:
while(true) {
    // ...
    
    if (playerStatus()) {
        break;
    }
}

Die Schleife wird also so lange durchlaufen, wie playerStatus() nicht wahr ist. Das ist doch eine klare Schleifenbedingung. Und die Prüfung ist am Ende der Schleife - das ist dann eine do while Schleife:
Code:
do {
   // ...
} while (!playerStatus())

Das !playerStatus() ist halt das negierte Ergebnis. Also das, was Du mit playerStatus() == false geprüft hättest. Aber - wie am Anfang gesagt: Das ist so unüblich. Das wird direkt so geschrieben.

Das war erst einmal ein Punkt. Ich muss da später noch einmal drauf schauen - da findet sich bestimmt mehr. Aber diese ausführlichen Erläuterungen sind doch recht zeitraubend so dass dies dann in Etappen kommen muss. Aber ich habe das Gefühl, dass Du derzeit diese lange Erläuterung noch brauchst und man Dir nicht kurze Optimierungen vorwerfen sollte :)
 

KonradN

Super-Moderator
Mitarbeiter
Was Du Dir ansehen kannst: Derzeit bewegt sich die zweite Schlange nur, wenn sich die erste Schlange in eine bestimmte Richtung bewegt hat. Sprich:
  • Bewegt sich die erste Schlange nach links, dann kann sich die zweite Schlange nach rechts oder links bewegen.
  • Bewegt sich die erste Schlange nach oben, dann kann sich die zweite Schlange nach oben oder unten bewegen.
Ist das so gewollt?
 
Die Aufteilung in Klassen wird erst wichtig, wenn Du auch anfängst objektorientiert zu arbeiten. Da bist du noch etwas am Anfang meine ich.

Ich baue da mal einfach ein fiktives Beispiel:
So wäre z.B. eine Klasse RandomPointGenerator denkbar. Der kann dann zufällige Punkte herausgeben.
Und da wäre dann eine mögliche Anforderung, dass keine Punkte doppelt vergeben werden. Der Generator muss sich also alle bereits generierten Punkte merken um dann immer zu prüfen, ob der neu generierte Punkt schon vergeben wurde.

Und dann macht es ggf. Sinn, davon mehrere Instanzen zu haben, weil die Anforderung ist:
  • Gold, Spieler und Tür dürfen nicht den gleichen Startpunkt haben
  • Schlangen können beliebig starten (Also auch auf Gold, Spieler und Tür - die ersten 5 Züge bewegt sich der Spieler und eine Kollision mit Schlangen am Startpunkt wird nicht geprüft) aber nicht aufeinander!

Das mag an den Haaren herbei gezogen sein, aber das macht den Ansatz etwas deutlicher- Du hast jetzt eine Klasse, die in sich etwas kapselt und eine gewisse Funktionalität hat. Und davon brauchst Du dann auch direkt mehrere Instanzen.

Aber noch einmal etwas zu dem Code:
Java:
            if (playerStatus() == true) {
                break;
            } else if (playerStatus() == false) {
                continue;
            }

playerStatus() gibt bereits ein boolean zurück. Da ist ein == true nicht notwendig. Das macht daraus ja ein true == true oder eben false == true.
Und das ist natürlich vom Ergebnis direkt ein true oder false. Es reicht also ein if (playerStatus()) aus.

Und bei einem if kommst Du in den else Zweig hinein, wenn das if nicht erfüllt ist. Wenn playerStatus() nicht true ist, dann ist doch klar, dass es false ist. Da ist also keine weitere Prüfung notwendig.

Damit hätten wir etwas wie:
Java:
            if (playerStatus()) {
                break;
            } else {
                continue;
            }

Nun können wir noch die Logik betrachten: Du bist in einer Schleife. Wenn playStatus wahr ist, dann verlässt Du die Schleife. Immer wenn Du sowas hast (der gradlinige Ablauf wird verlassen durch return, break, continue oder throw - ich hoffe ich habe nichts vergessen.) dann brauchst Du kein else Zweig!

Den kannst Du also wegnehmen und einfach die Befehle aus dem else Zweig so hin schreiben:
Java:
            if (playerStatus()) {
                break;
            }
            continue;

Und an dieser Stelle kann das continue auch direkt weg. Das ist am Ende des Blocks der Schleife und damit ist der Block vorbei. Ein einzelnes, unbedingtes continue macht keinen Sinn. Wenn danach noch Befehle kämen, wäre der Code nicht erreichbar:
Java:
while (....) {
    // ...
   
    continue;
   
    // Code hier würde nie ausgeführt!
}

Und dann kommen wir bei der While-Schleife zu einem weiteren Punkt. Derzeit hast Du:
Java:
while(true) {
    // ...
   
    if (playerStatus()) {
        break;
    }
}

Die Schleife wird also so lange durchlaufen, wie playerStatus() nicht wahr ist. Das ist doch eine klare Schleifenbedingung. Und die Prüfung ist am Ende der Schleife - das ist dann eine do while Schleife:
Code:
do {
   // ...
} while (!playerStatus())

Das !playerStatus() ist halt das negierte Ergebnis. Also das, was Du mit playerStatus() == false geprüft hättest. Aber - wie am Anfang gesagt: Das ist so unüblich. Das wird direkt so geschrieben.

Das war erst einmal ein Punkt. Ich muss da später noch einmal drauf schauen - da findet sich bestimmt mehr. Aber diese ausführlichen Erläuterungen sind doch recht zeitraubend so dass dies dann in Etappen kommen muss. Aber ich habe das Gefühl, dass Du derzeit diese lange Erläuterung noch brauchst und man Dir nicht kurze Optimierungen vorwerfen sollte :)
Hall Karsten,
Genau solch eine Erläuterung habe ich benötigt, um zu sehen, wo ich noch Logikfehler begehe. Dann werde ich wohl doch noch weiter an dem Projekt arbeiten und so meine Erfahrungen machen und mich verbessern. Die Hilfe mit den Schleifen ist wirklich sehr nützlich! Das zeigt mir klar, woran ich noch arbeiten muss, bevor ich neue Konzepte erlerne.
Ich habe gesehen, dass viele hier Problemlösungen für ihre Programme suchen, aber das ist nicht mein Bestreben. Nur wer selbst Probleme löst, kann sich verbessern, weshalb ich sehr dankbar für den kleinen Denkanstoß zu den Schleifen und Methoden bin. :)

Ich werde mich dann mal an mein Werk machen und versuchen, mit dem Wissensstand, den ich habe und die Hilfe von ihnen, das Programm zu optimieren und logisch zu verbessern. Sollte es hier niemanden stören, würde ich, sobald ich denke, es ist optimiert, den Code nochmals posten. Ich möchte niemanden zur Last fallen ^^

Ich wünsche dir noch ein angenehmes Wochenende!
Was die Objekterzeugung angeht könnte man längerfristig zu "creational patterns" recherchieren (es könnten ja mehr werden und die Objekte unterscheiden sich mehr oder weniger stark): Multiton, (abstract) factory pattern, prototype,...
Vielen Dank für den Tipp! Ich werde es mal googeln und schauen, ob ich es zumindest zum Teil verstehe und mir nützliche Informationen mitnehmen kann.

Ich wünsche dir ein schönes Wochenende! :)
 
Was Du Dir ansehen kannst: Derzeit bewegt sich die zweite Schlange nur, wenn sich die erste Schlange in eine bestimmte Richtung bewegt hat. Sprich:
  • Bewegt sich die erste Schlange nach links, dann kann sich die zweite Schlange nach rechts oder links bewegen.
  • Bewegt sich die erste Schlange nach oben, dann kann sich die zweite Schlange nach oben oder unten bewegen.
Ist das so gewollt?
Oh nein, das ist so eigentlich nicht gewollt o_O Ich schätze, das liegt an der Verschachtelung der if-Bedingung? Ich werde es nochmals genauer ansehen und schauen, ob ich das Problem finde. Ist mir bis jetzt gar nicht aufgefallen. Das zeigt einem wirklich mit Härte, wie viele Fehler man macht.
 

KonradN

Super-Moderator
Mitarbeiter
Ich schätze, das liegt an der Verschachtelung der if-Bedingung?
Ja genau. Bei sowas ist immer hilfreich, wenn man dies auch in Worten überlegt. Und auch wieder in Methoden denken (Also bei Worten wäre das die Nutzung einer neuen Beschreibung, die dann im Detail später erläutert wird). Hier wäre das:

Dein Programm soll ja an der Stelle machen:
  • Bewege Schlange1
  • Bewege Schlange2

Und Bewege Schlange macht:
- ... (Spare ich mir jetzt - das hast Du ja prinzipiell für Schlange1 schon richtig gemacht)
 
Ja genau. Bei sowas ist immer hilfreich, wenn man dies auch in Worten überlegt. Und auch wieder in Methoden denken (Also bei Worten wäre das die Nutzung einer neuen Beschreibung, die dann im Detail später erläutert wird). Hier wäre das:

Dein Programm soll ja an der Stelle machen:
  • Bewege Schlange1
  • Bewege Schlange2

Und Bewege Schlange macht:
- ... (Spare ich mir jetzt - das hast Du ja prinzipiell für Schlange1 schon richtig gemacht)
Hallo Konrad,
tut mir leid für die verspätete Antwort. Durch Kinder und Ehefrau habe ich nicht zu viel Zeit. Programmieren ist nur ein Hobby ^^

Ich habe, wie du mir sagtest, etwas überlegt, wie geprüft werden kann, ob sich auf den Koordinaten schon ein Objekt befindet, und wenn nicht, so soll er neue Koordinaten erstellen. Die Schlangenbewegungen habe ich nun erst einmal getrennt geschrieben, wobei ich überlege dies noch etwas logischer aufzubauen.
Ich kann ja nur mit dem arbeiten, was ich bis jetzt gelernt habe. ;)

Meine Lösung für das Problem mit den belegten Koordinaten möchte nur noch nicht ganz funktionieren. Mein Gedanke ist dieser:
Die erste Schleife ist bei 0. Dann wird die zweite Schleife aufgerufen, die ebenfalls bei 0 anfängt. In der zweiten Schleife wird per do while Schleife getestet, ob die Indexposition 0, repräsentiert durch die erste Schleife, sich auf einem anderen Punkt aus dem Array befindet, repräsentiert wird dies durch die zweite Schleife. Das müsste doch für jeden Index des Arrays passieren. So mein Gedanke grübel

Hier ist meine Lösung für das Problem mit den doppelt belegten Koordinaten:

Java:
    public void spawnSetter() {
        ArrayList<Point> Point = new ArrayList<Point>();
        Point.add(player);
        Point.add(snake);
        Point.add(snake2);
        Point.add(teleport1);
        Point.add(teleport2);
        Point.add(teleport3);
        Point.add(teleport4);
        Point.add(door);
        Point.add(gold);
        Point.add(gold2);
       
        for(int i = 0; i < Point.size(); i++) {
            for(int j = 0; j < Point.size(); j++) {
                do {
                    Point.get(i).setLocation(randomX(), randomY());
                }while(Point.get(i).equals(Point.get(j)));
            }
        }
    }

Grüßle
 
Zuletzt bearbeitet:
Hallo Konrad,
tut mir leid für die verspätete Antwort. Durch Kinder und Ehefrau habe ich nicht zu viel Zeit. Programmieren ist nur ein Hobby ^^

Ich habe, wie du mir sagtest, etwas überlegt, wie geprüft werden kann, ob sich auf den Koordinaten schon ein Objekt befindet, und wenn nicht, so soll er neue Koordinaten erstellen. Die Schlangenbewegungen habe ich nun erst einmal getrennt geschrieben, wobei ich überlege dies noch etwas logischer aufzubauen.
Ich kann ja nur mit dem arbeiten, was ich bis jetzt gelernt habe. ;)

Meine Lösung für das Problem mit den belegten Koordinaten möchte nur noch nicht ganz funktionieren. Mein Gedanke ist dieser:
Die erste Schleife ist bei 0. Dann wird die zweite Schleife aufgerufen, die ebenfalls bei 0 anfängt. In der zweiten Schleife wird per do while Schleife getestet, ob die Indexposition 0, repräsentiert durch die erste Schleife, sich auf einem anderen Punkt aus dem Array befindet, repräsentiert wird dies durch die zweite Schleife. Das müsste doch für jeden Index des Arrays passieren. So mein Gedanke grübel

Hier ist meine Lösung für das Problem mit den doppelt belegten Koordinaten:

Java:
    public void spawnSetter() {
        ArrayList<Point> Point = new ArrayList<Point>();
        Point.add(player);
        Point.add(snake);
        Point.add(snake2);
        Point.add(teleport1);
        Point.add(teleport2);
        Point.add(teleport3);
        Point.add(teleport4);
        Point.add(door);
        Point.add(gold);
        Point.add(gold2);
      
        for(int i = 0; i < Point.size(); i++) {
            for(int j = 0; j < Point.size(); j++) {
                do {
                    Point.get(i).setLocation(randomX(), randomY());
                }while(Point.get(i).equals(Point.get(j)));
            }
        }
    }

Grüßle
Ich konnte leider meine vorherige Antwort nicht mehr bearbeiten, da scheinbar 30 Minuten abgelaufen sind o_O, aber ich habe den Fehler erkannt, so denke ich und eine neue Lösung geschrieben. Diesmal scheint alles zu laufen. Leider weiß ich noch nicht wie ich meinen Code debugge, daher kann ich nur testen und schauen.


Java:
    public void spawnSetter() {
        ArrayList<Point> Point = new ArrayList<Point>();
        Point.add(player);
        Point.add(snake);
        Point.add(snake2);
        Point.add(teleport1);
        Point.add(teleport2);
        Point.add(teleport3);
        Point.add(teleport4);
        Point.add(door);
        Point.add(gold);
        Point.add(gold2);
        
        for(int i = 0; i < Point.size(); i++) {
            for(int j = 1; j < Point.size(); j++) {
                
                Point.get(i).setLocation(randomX(), randomY());
                
                if(Point.get(i).equals(Point.get(j))) {
                    Point.get(i).setLocation(randomX(), randomY());
                }
                else {
                    break;
                }
            }
        }
    }
 

KonradN

Super-Moderator
Mitarbeiter
Das ist so noch nicht ganz richtig.

Es macht immer Sinn, so eine Aufgabe aufzuteilen. Wie wäre es denn zu beschreiben?

Das wäre doch etwas wie:

Für jede Position des Arrays:
- füge neue Koordinaten ein, die noch nicht im Array vorhanden waren.

Ermittlung neuer Koordinaten, die noch nicht im Array sind:
  • Ermittel eine neue Koordinate
  • So lange die Koordinate bereits im Array ist: wiederhole den vorherigen Schritt
  • Gib die ermittelte Koordinate zurück

Das kann man dann in Code schreiben. Da Du ja mehrere Coordinaten setzen willst, könnte man die auch als Parameter übergeben. Das wäre dann ein typischer varargs Parameter.


Java:
public static void initializePoints(Point... points) {
    // points ist hier nun ein Array.
    
    for (int index=0; index < points.length; index++) {
        points[i].setLocation(getNewUniqueLocation(points));
    }
}

public static Point getNewUniqueLocation(Point[] points) {
    Point result = new Point();
    do {
        result.setLocation(randomX(), randomY());
    } while (pointInArray(points, result));
    return result;
}

public static boolean pointInArray(Point[] points, Point value) {
    for (Point point: points) {
        if (point.equals(value)) {
            return true;
        }
    }
    return false;
}

Das wäre dann eine einfach zu verstehende Lösung - die halt das eigentliche Problem aufgeteilt hat in mehrere kleine Probleme, die jedes nun einfach zu überschauen ist.
 

KonradN

Super-Moderator
Mitarbeiter
Ach ja - der Aufruf der Methode fehlte noch - da kannst Du einfach Points angeben, also etwas wie:
Code:
initializePoints(player, snake, snake2, teleport1, teleport2, teleport3, teleport4, door, gold, gold2);
 
Das ist so noch nicht ganz richtig.

Es macht immer Sinn, so eine Aufgabe aufzuteilen. Wie wäre es denn zu beschreiben?

Das wäre doch etwas wie:

Für jede Position des Arrays:
- füge neue Koordinaten ein, die noch nicht im Array vorhanden waren.

Ermittlung neuer Koordinaten, die noch nicht im Array sind:
  • Ermittel eine neue Koordinate
  • So lange die Koordinate bereits im Array ist: wiederhole den vorherigen Schritt
  • Gib die ermittelte Koordinate zurück

Das kann man dann in Code schreiben. Da Du ja mehrere Coordinaten setzen willst, könnte man die auch als Parameter übergeben. Das wäre dann ein typischer varargs Parameter.


Java:
public static void initializePoints(Point... points) {
    // points ist hier nun ein Array.
   
    for (int index=0; index < points.length; index++) {
        points[i].setLocation(getNewUniqueLocation(points));
    }
}

public static Point getNewUniqueLocation(Point[] points) {
    Point result = new Point();
    do {
        result.setLocation(randomX(), randomY());
    } while (pointInArray(points, result));
    return result;
}

public static boolean pointInArray(Point[] points, Point value) {
    for (Point point: points) {
        if (point.equals(value)) {
            return true;
        }
    }
    return false;
}

Das wäre dann eine einfach zu verstehende Lösung - die halt das eigentliche Problem aufgeteilt hat in mehrere kleine Probleme, die jedes nun einfach zu überschauen ist.
Wow, das muss ich mir erst einmal ein wenig anschauen, um das gänzlich zu verstehen. Ich danke dir wirklich sehr für die ganze Zeit und Mühe, die du dir gemacht hast! Ich werde mir das erstmal verinnerlichen und schauen, ob ich mit der gewonnenen Erfahrung das Projekt verbessern und ausbauen kann. ;)
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
V Anfängerfrage: HelloWorld läuft nicht Java Basics - Anfänger-Themen 3
F if else if anfängerfrage Java Basics - Anfänger-Themen 22
P Anfängerfrage, Primitiv,komplex Java Basics - Anfänger-Themen 1
pkm Erste Schritte Anfängerfrage zu ::new Java Basics - Anfänger-Themen 4
A Anfängerfrage Java Basics - Anfänger-Themen 7
M Erstellung Interfaces....totale Anfängerfrage Java Basics - Anfänger-Themen 16
W DNS Name auslesen + weitere Anfängerfrage Java Basics - Anfänger-Themen 4
R Anfängerfrage zu Methoden in Vererbte Klassen Java Basics - Anfänger-Themen 2
F Erste Schritte (Gelöst) Anfängerfrage Arraylist ausserhalb der Main Methode Java Basics - Anfänger-Themen 2
DeVolt Anfängerfrage zu util.scanner Java Basics - Anfänger-Themen 2
T Anfängerfrage zu Schleifen und Arrays Java Basics - Anfänger-Themen 5
B Collections ArrayList füllen - Anfängerfrage Java Basics - Anfänger-Themen 1
Shams Anfängerfrage zu jnlp Java Basics - Anfänger-Themen 0
T Kleine Anfängerfrage :) Java Basics - Anfänger-Themen 4
I Anfängerfrage JPanel repaint() Java Basics - Anfänger-Themen 6
F Anfängerfrage zu extends Java Basics - Anfänger-Themen 12
A Anfängerfrage: Zahlformat prüfen Java Basics - Anfänger-Themen 4
I Anfängerfrage: Fehlersuche Java Basics - Anfänger-Themen 2
A Methoden Anfängerfrage: 2 Listen Vergleichen Java Basics - Anfänger-Themen 7
L Anfängerfrage zu TileMap Java Basics - Anfänger-Themen 4
J anfängerfrage Java Basics - Anfänger-Themen 10
J Anfängerfrage HelloWorld? cmd-Problem Java Basics - Anfänger-Themen 35
J Anfängerfrage zu Grundlagen von Packages Java Basics - Anfänger-Themen 7
J Anfängerfrage zur Variablen Java Basics - Anfänger-Themen 11
J Anfängerfrage :-) Java Basics - Anfänger-Themen 5
M Banale Anfängerfrage Java Basics - Anfänger-Themen 3
Y Anfängerfrage zu array(-Syntax) Java Basics - Anfänger-Themen 6
J Leichte Java Anfängerfrage. Bitte schnelle Antwort. :) Java Basics - Anfänger-Themen 10
U Anfängerfrage - Multithreading Java Basics - Anfänger-Themen 8
T Aufrufen von get-Methode aus anderer Klasse (absolute Anfängerfrage) Java Basics - Anfänger-Themen 2
G Anfängerfrage zu "@Override" Java Basics - Anfänger-Themen 5
N Anfängerfrage richtige Syntax und Frage zu Vector Java Basics - Anfänger-Themen 7
A Anfängerfrage - array required, but java.lang.String found Java Basics - Anfänger-Themen 7
M Kleine Anfängerfrage Java Basics - Anfänger-Themen 10
S Anfängerfrage zu Array Java Basics - Anfänger-Themen 8
K Anfängerfrage: Fehlermeldung Java Basics - Anfänger-Themen 6
D Anfängerfrage N. Office Access NOA: setHidden und dann . Java Basics - Anfänger-Themen 2
N Anfängerfrage Java Basics - Anfänger-Themen 14
N anfängerfrage. returnwerte Java Basics - Anfänger-Themen 3
Gama Importieren von Klassen [Anfängerfrage] Java Basics - Anfänger-Themen 3
G Anfängerfrage Java Basics - Anfänger-Themen 11
B Anfängerfrage zu Swing "Reload" Java Basics - Anfänger-Themen 2
N Anfängerfrage bezüglich Speicherverwaltung Java Basics - Anfänger-Themen 3
G Anfängerfrage zu Threads Java Basics - Anfänger-Themen 14
Q Anfängerfrage Java Basics - Anfänger-Themen 6
J Anfängerfrage: wie externe Dateien importieren? Java Basics - Anfänger-Themen 5
S Anfängerfrage Java Basics - Anfänger-Themen 7
G Anfängerfrage zu Vererbung Java Basics - Anfänger-Themen 6
B Anfängerfrage zu 'NoClassDefFoundError' Java Basics - Anfänger-Themen 2
J IO Frage Hex-Output - Anfängerfrage Java Basics - Anfänger-Themen 5
T Anfängerfrage -> Projekt Java Basics - Anfänger-Themen 2
C Anfängerfrage ->Objekte und Arrays Java Basics - Anfänger-Themen 4
V Anfängerfrage Java Basics - Anfänger-Themen 8
E RMI Anfängerfrage Java Basics - Anfänger-Themen 10
DEvent anfängerfrage: wieso layout erst beim verändern? Java Basics - Anfänger-Themen 6
G Anfängerfrage Java Basics - Anfänger-Themen 2
P Wie kann ich in meinem Java Programm etwas dauerhaft speichern? Java Basics - Anfänger-Themen 5
P Wie kann ich beispielsweise Speicherstände eines Spiels DAUERHAFT in meinem Programm speichern? Java Basics - Anfänger-Themen 3
httprt Probleme bei dem erstellen von leveln in meinem Spiel Java Basics - Anfänger-Themen 2
J Frage zu meinem Code (OOP) Java Basics - Anfänger-Themen 4
NadimArazi Wie kann ich eine collision detection für die Paddles in meinem Pong Programm hinzufügen? Java Basics - Anfänger-Themen 4
A wie kann ich es in meinem Programm rein tun Java Basics - Anfänger-Themen 8
C konstruktiver Kritik zu meinem Lösungsansatz Java Basics - Anfänger-Themen 22
E extern Datei von meinem Computer aufmachen Java Basics - Anfänger-Themen 5
J Erste Schritte Was mache ich in meinem Code falsch. Java Basics - Anfänger-Themen 3
W Wo ist der Wurm in meinem Grundverständnis von Klassen? Java Basics - Anfänger-Themen 22
K Wie kontrolliere ich ob ich die Zahl in meinem Array schon hab? Java Basics - Anfänger-Themen 9
B Grundsatzfragen zu meinem neuen Projekt Einnahmen-Ausgaben App Java Basics - Anfänger-Themen 8
K Error bei meinem Programm - Hilfe Java Basics - Anfänger-Themen 8
R Was muss ich an meinem Code ändern? Java Basics - Anfänger-Themen 2
S Hilfe bei meinem Code [Schleife]? Java Basics - Anfänger-Themen 5
M Problem mit meinem Programm Java Basics - Anfänger-Themen 6
W Dezimalzahl in Binär umwandeln - Was sollte ich an meinem Programm verbessern? Java Basics - Anfänger-Themen 5
W Wie ziehe ich positive ungerade Zahlen von meinem Hauptwert ab? Java Basics - Anfänger-Themen 17
V Operatoren Was will mir die Tabelle in meinem Lehrbuch sagen? (logische Operatoren) Java Basics - Anfänger-Themen 4
N Problem bei meinem Code Java Basics - Anfänger-Themen 10
P Erste Schritte Bitte ein paar Erklärungen zu meinem Code Java Basics - Anfänger-Themen 6
H OOP, wie gehts richtig? (Beispiel von meinem Prof) Java Basics - Anfänger-Themen 6
H IOException in meinem Programm Java Basics - Anfänger-Themen 7
K Frage zu meinem ersten Programm Java Basics - Anfänger-Themen 5
K Frage zu meinem Programm Java Basics - Anfänger-Themen 25
F Methoden Kleines Problem mit meinem Glücksrad... Java Basics - Anfänger-Themen 9
O Wert in einer URL hinzufügen (in meinem Beispiel Google) Java Basics - Anfänger-Themen 7
M Wo ist der Fehler in meinem Programm? Java Basics - Anfänger-Themen 12
G Welche Java-Version auf meinem Rechner? Java Basics - Anfänger-Themen 2
D Keine Ausgabe in meinem Helden Programm Java Basics - Anfänger-Themen 2
M kurze frage zu meinem Code ... Java Basics - Anfänger-Themen 3
S Wie ist folgender Kommentar in meinem Ant file zu verstehen..? Java Basics - Anfänger-Themen 0
N Frage zu meinem Calculator Java Basics - Anfänger-Themen 6
D Verschiedene Fragen zu meinem Projekt Java Basics - Anfänger-Themen 6
F Hilfe bei meinem Spiel Java Basics - Anfänger-Themen 3
X Datentypen Probleme mit Char bei meinem 1. Spiel Java Basics - Anfänger-Themen 20
F Wie rechne ich bei meinem Code, die Wahrscheinlichkeit von Fall X aus? Java Basics - Anfänger-Themen 3
D Problem mit meinem ersten JOptionPane - Fatal exception occurred. Program will exit. Java Basics - Anfänger-Themen 6
K Hilfe, komme nicht weiter in meinem JAVA-Spiel Java Basics - Anfänger-Themen 3
C ArrayIndexOutOfBoundsException bei meinem ersten objektiorientierten Programm Java Basics - Anfänger-Themen 4
H frage zu meinem quellcode Java Basics - Anfänger-Themen 10
B Wo ist der Fehler in meinem Script Java Basics - Anfänger-Themen 4
Gonzalez Eingabe des Benutzers mittels readLine()-Methode. Klappt in meinem Beispiel nicht! Java Basics - Anfänger-Themen 7
M Fehler in meinem Quicksort! Java Basics - Anfänger-Themen 21

Ähnliche Java Themen


Oben