JavaRush /Java-Blog /Random-DE /Java-Spiel für Anfänger
timurnav
Level 21

Java-Spiel für Anfänger

Veröffentlicht in der Gruppe Random-DE
Hallo Freunde und zukünftige Kollegen! Java-Spiel für Anfänger - 1Vor kurzem habe ich einen Test zur Teilnahme an einem echten Projekt abgelegt, ihn bestanden, aber zufälligerweise konnte ich aufgrund persönlicher Umstände nicht am RP selbst teilnehmen. Nach so interessanten Aufgaben wie dem RP-Test wurden die üblichen Kursaufgaben zu einem weniger attraktiven Zeitvertreib, zumal ich die meisten davon bereits gelöst hatte. Damit mein Talent nicht zum Weiterlernen verschwendet wird, habe ich beschlossen, ein Multiplayer-Webspiel zu entwickeln. Links zu anderen Spielen:
  1. Fortsetzung dieses Artikels
  2. 2048
Tic Tac Toe schien mir das einfachste Spiel zu sein, also beschloss ich, die Aufgabe in mehrere Unteraufgaben zu unterteilen:
  1. Konsolenanwendung zum Testen der Spiellogik
  2. Mehrspieler
  3. Anhängen einer Spielerdatenbank an eine Konsolenanwendung
  4. Frontend-Design erstellen, Seitenvorlagen schreiben, Spieloberfläche
  5. Alles zusammenfügen
Es besteht die Möglichkeit, dass ich für eine solche Reihenfolge beschimpft werde, und höchstwahrscheinlich werden alle ernsthaften Projekte in einer völlig anderen Reihenfolge erstellt. Ich werde sofort antworten und einen Beitrag darüber „für Anfänger“ schreiben, damit alle (einschließlich mir) kann das lernen :) Nun, fangen wir an, eine Konsolenanwendung zu schreiben! Ich werde die gleichen Schritte wie bei den großen Level-20-Herausforderungen befolgen. Was ist im Spiel Tic-Tac-Toe?!
  1. Feld
  2. Zwei Spieler wechseln sich ab, einer setzt ein Kreuz, der andere eine Null. Es ist einfach.
Wir machen das Feld zu einem Standard-3x3-Feld. Wie kann ein solches Feld gespeichert werden? Die erste Option ist ein zweidimensionales Array. Welche Elemente sollte dieses Array enthalten? Die Antwort ist, dass wir darüber nachdenken müssen, was wir mit diesen Elementen machen werden, nämlich Anzeigen und Vergleichen, um den Gewinner zu ermitteln. Wenn wir sie nur auf dem Bildschirm anzeigen würden, wäre es logisch, sie als String beizubehalten, dann würde das Array selbst und die Anzeige auf dem Bildschirm in einer Schleife etwa so aussehen:
String[][] strings = {{"O", "O", "_"},
                    {"_", "X", "O"},
                    {"X", "X", "X"},
for (String [] ss : strings){
    for (String s : ss) System.out.print(s + " ");
    System.out.println(); //для перевода строки
}
Der Bildschirm würde Folgendes anzeigen:
O O _
_ X O
X X X
Aber neben der Anzeige gibt es bei uns auch einen Vergleich von Werten, und hier sind bereits Optionen möglich. Sie können Zeichenfolgen vergleichen, Sie können eine spezielle Aufzählungsklasse ( enum) erstellen, aber ich würde es vorziehen, Zahlen zu vergleichen und sie nur dann durch „X“ und „O“ zu ersetzen, wenn sie auf dem Bildschirm angezeigt werden. Sei es zum Beispiel 1 – „X“, 2 – „O“, 0 – „_“. Wie überprüft man also ein Feld auf eine dreifache X- oder O-Übereinstimmung?
Der allererste Algorithmus überprüft das gesamte Feld
int[][] canvas = {{00, 01, 02},
                 {10, 11, 12},
                 {20, 21, 22}}
Gewinnkombinationen:
00-01-02, 10-11-12, 20-21-22, 00-10-20, 01-11-21, 02-12-22, 00-11-22, 20-11-02 — всего 8.
Die Überprüfung erfolgt durch Zahlenvergleich, aber es stellt sich heraus, dass Sie jedes Mal das GESAMTE Feld, also alle 8 Kombinationen, überprüfen müssen. Das ist natürlich nicht viel, das ist keine Suche nach Armstrong-Zahlen im Bereich von 0 bis 1 Milliarde, hier gibt es kaum mehr als gar keine Berechnungen, aber man möchte trotzdem etwas Optimaleres, als das gesamte Feld zu überprüfen. Die zweite Idee, die mir kam, war, nur die Zelle zu überprüfen, die beim vorherigen Zug markiert war, damit wir immer noch den Gewinner ermitteln können, weil wir wissen, wer diesen Zug gemacht hat. Anstelle aller 8 Kombinationen erhalten wir also je nach Zelle nur 2, 3 oder 4 Kombinationen, siehe Bild: Java-Spiel für Anfänger - 2Jetzt müssen wir herausfinden, wie wir bestimmen, welche Kombination gestartet werden muss? Hier wurde mir klar, dass die Verwendung eines zweidimensionalen Arrays nicht sehr praktisch ist. Ich beschloss, andere Optionen in Betracht zu ziehen. Zuerst kam ich auf die Idee, dass das Feld in einer neunstelligen Zahl gehalten werden kann, zum Beispiel kann das gleiche Feld, das wir auf dem Bildschirm angezeigt haben, so geschrieben werden: 220012111, ich werde in meinen Fingern erklären, was es ist ist... Der Code ist derselbe, 1 - „X“, 2 – „O“, 0 – „ “, was 220012111 = „OO__XOXXX“ bedeutet, oder wenn Sie nach jeder dritten Ziffer einen Zeilenumbruch und Leerzeichen für hinzufügen Klarheit:
О О _
_ Х О
Х Х Х
Auch hier wurde ein Anzeigegerät erfunden, praktisch für die Aufbewahrung, aber zum Vergleich unpraktisch! Die Lösung wurde gefunden, als ich die Zellen von 1-9 nummerierte, dann dachte ich mir, denn beim Programmieren beginnt der Countdown bei 0 und nummerierte es wie auf dem Bild. Java-Spiel für Anfänger - 3Sind euch keine Besonderheiten aufgefallen? Wenn Sie sich das Bild oben ansehen, wird deutlich, dass Lösungen mit 2 Kombinationen eine ungerade Seriennummer haben, 4 Kombinationen haben die Seriennummer 4, 3 Kombinationen haben den Rest. Daher bin ich zu dem Schluss gekommen, dass das Spielfeld in einem regelmäßigen Zahlenarray gehalten werden muss: einfache Iteration zwischen Zahlen, die Möglichkeit zum Vergleich gemäß dem gewählten Algorithmus, einfache Ausgabe auf dem Bildschirm. Was den Vergleichsalgorithmus selbst betrifft. Gehen wir der Reihe nach vor: Bei allen Optionen erfolgt eine Prüfung der Zeile und Spalte, wir prüfen nur diese. Wenn die Suche kein Ergebnis liefert, überprüfen wir die Zellennummer auf gerade/ungerade. Wenn sie ungerade ist, kehren wir zum Spiel zurück. Eine weitere Überprüfung macht keinen Sinn. Wenn sie gerade ist, überprüfen wir, ob diese Zelle auf der Nummer liegt linke Diagonale, die Zahlen dieser Diagonale haben bei Division durch 4 einen Rest von 0. Wenn es liegt, prüfen wir auf Übereinstimmungen, wenn keine Übereinstimmungen gefunden werden, dann prüfen wir auf die Zahl 4, wenn nicht, kehren wir zum Spiel zurück, wenn Ja, wir gehen den Code weiter durch und geben das Ergebnis der Überprüfung der letzten Diagonale zurück. Für eine unvorbereitete Person ist dies wahrscheinlich schwer zu verstehen, nachdem sie die oben stehenden Buchstaben gelesen hat, aber jemand könnte sagen, dass der Code selbst viele Buchstaben enthält, was einfacher sein kann. Ich werde dies gerne besprechen. Wir haben das Feld geklärt, jetzt müssen wir uns mit zwei Benutzern befassen, die sich abwechseln, und jeder von ihnen hat sein eigenes Zeichen, X oder O. In der ersten Phase haben wir keine Multi-User-Funktionalität, also die Am einfachsten wäre es, die Symbole einzeln zu verwenden. X macht immer den ersten Zug, O macht immer den zweiten, dann wieder X und so weiter. Es muss überprüft werden ( true/false ), und wenn true – dann ist der aktuelle Spieler Zelle, die sie wählen. Hier brauchen wir unsere unvergesslichen BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); Spieler. Die Spieler geben die Zellennummern in die Konsole ein und drücken die Eingabetaste, um einen Zug auszuführen. Die Zelle, die der eingegebenen Zahl entspricht, ändert ihren Wert von 0 auf 1 oder 2, abhängig vom aktuellen Status des Kontrollkästchens, der im obigen Absatz besprochen wurde. Hier ist es wichtig, die Eingabe zu validieren, damit niemand X in O ändern kann, wenn die Zelle bereits gefüllt ist :) Was kann der Spieler in die Konsole eingeben?
  1. leere Zeile
  2. Buchstaben, Satzzeichen, Klammern ... in einem Wort, Nicht-Zahlen
  3. falsche Zahlen – negativ oder außerhalb der Arraygröße, belegte Zellen.
Die Standardmethode zum Abrufen einer Ziffer aus einer Zeichenfolge ist die statische Methode parseInt der Integer-Klasse. Integer.parseInt("2");Sie löst eine Ausnahme aus NumberFormatException, wenn keine Ziffer aus einer bestimmten Zeichenfolge ermittelt werden kann. Wir können Schutz vor den ersten beiden Punkten bieten, indem wir diese Ausnahme abfangen. Für den dritten Punkt würde ich eine andere Methode erstellen, die den eingegebenen Wert überprüft. Am korrektesten wäre es jedoch, die Zeichenfolgenanforderung in eine separate Methode zu verschieben, in der die Validierung durchgeführt wird und die nur eine Zahl zurückgibt. Zusammenfassend haben wir ein Feld erstellt, eine Methode erstellt, die es anzeigt, eine Methode erstellt, die überprüft, „Hat dieser Spieler mit einer Stunde Vorsprung gewonnen?“, und die eingegebenen Zahlen validiert. Es bleibt nur noch sehr wenig zu tun: Überprüfen Sie, ob ein Unentschieden vorliegt – eine separate Methode, die das Array durchläuft, nach 0 sucht und die Spielergebnisse anzeigt. Das ist alles, der Code ist fertig, das Spiel ist klein geworden, nur eine Klasse, also können harte Kopierer, ohne es zu verstehen, einfach alles in ihr Projekt kopieren und es alleine ausführen, ich selbst war so, aber Jetzt versuche ich, das nicht zu tun und empfehle es niemandem :) Viel Glück an alle beim Erlernen von JAVA! PS: Die restlichen Punkte – Multiplayer und Datenbank kommen später, ich habe bereits mit dem Studium des Materials begonnen :)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class GameField {

    static int [] canvas = {0,0,0,
                            0,0,0,
                            0,0,0};

    //012, 345, 678, 036, 147, 258, 048, 246
    public static void main(String[] args){

        boolean b;
        boolean isCurrentX = false;
        do {
            isCurrentX = !isCurrentX;
            drawCanvas();
            System.out.println("mark " + (isCurrentX ? "X" : "O"));
            int n = getNumber();
            canvas[n] = isCurrentX ? 1 : 2;
            b = !isGameOver(n);
            if (isDraw()){
                System.out.println("Draw");
                return;
            }
        } while (b);
        drawCanvas();
        System.out.println();

        System.out.println("The winner is " + (isCurrentX ? "X" : "O") + "!");
    }

    static int getNumber(){
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        while (true){
            try {
                int n = Integer.parseInt(reader.readLine());
                if (n >= 0 && n < canvas.length && canvas[n]==0){
                    return n;
                }
                System.out.println("Choose free cell and enter its number");
            } catch (NumberFormatException e) {
                System.out.println("Please enter the number");
            } catch (IOException e) {
            }
        }
    }

    static boolean isGameOver(int n){
        // 0 1 2
        // 3 4 5
        // 6 7 8
        //поиск совпадений по горизонтали
        int row = n-n%3; //номер строки - проверяем только её
        if (canvas[row]==canvas[row+1] &&
                canvas[row]==canvas[row+2]) return true;
        //поиск совпадений по вертикали
        int column = n%3; //номер столбца - проверяем только его
        if (canvas[column]==canvas[column+3])
            if (canvas[column]==canvas[column+6]) return true;
        //мы здесь, значит, первый поиск не положительного результата
        //если Bedeutung n находится на одной из граней - возвращаем false
        if (n%2!=0) return false;
        //проверяем принадлежит ли к левой диагонали Bedeutung
        if (n%4==0){
            //проверяем есть ли совпадения на левой диагонали
            if (canvas[0] == canvas[4] &&
                    canvas[0] == canvas[8]) return true;
            if (n!=4) return false;
        }
        return canvas[2] == canvas[4] &&
                canvas[2] == canvas[6];
    }

    static void drawCanvas(){
        System.out.println("     |     |     ");
        for (int i = 0; i < canvas.length; i++) {
            if (i!=0){
                if (i%3==0) {
                    System.out.println();
                    System.out.println("_____|_____|_____");
                    System.out.println("     |     |     ");
                }
                else
                    System.out.print("|");
            }

            if (canvas[i]==0) System.out.print("  " + i + "  ");
            if (canvas[i]==1) System.out.print("  X  ");
            if (canvas[i]==2) System.out.print("  O  ");
        }
        System.out.println();
        System.out.println("     |     |     ");
    }

    public static boolean isDraw() {
        for (int n : canvas) if (n==0) return false;
        return true;
    }
}
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION