Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Lernen Erstellung Einer Zahlenratespiel-Konsolenanwendung | Erstellung von Konsolenanwendungen mit Node.js
Backend-Entwicklung mit Node.js und Express.js

Erstellung Einer Zahlenratespiel-Konsolenanwendung

Swipe um das Menü anzuzeigen

In diesem Kapitel wirst du deine Fähigkeiten in der Entwicklung von Konsolenanwendungen erweitern, indem wir gemeinsam eine spannende Zahlenraten-Spiel-App erstellen. Dieses interaktive Spiel fordert die Spieler heraus, ihre Intuition zu nutzen, indem sie eine zufällig generierte Zahl innerhalb eines vorgegebenen Bereichs erraten. Dabei werden wir grundlegende Konzepte wie

  • Zufallszahlengenerierung,
  • Eingabevalidierung,
  • Benutzerinteraktion,
  • sowie das Speichern von Spielergebnissen in einer Datei kennenlernen.

Herausforderung

Stell dir vor, du tauchst in eine App ein, die Spannung und Neugier verspricht. Die Spieler sind eingeladen, eine geheimnisvoll ausgewählte Zahl innerhalb eines vorgegebenen Bereichs zu erraten. Die App gibt sofortiges Feedback zu jedem Versuch und führt eine genaue Zählung der abgegebenen Tipps.

Dieses praxisnahe Beispiel bietet die Möglichkeit, die Fähigkeiten im Bau von CLI-Apps zu verfeinern und zeigt, wie interaktive Programme gestaltet werden können.

Ergebnis-App

Erlebe die Anwendung in Aktion! Unten findest du ein GIF, das die spannende Zahlenraten-Spiel-App zeigt, die du erstellen wirst:

Entwicklung einer Konsolenanwendung für ein Ratespiel

Es stehen zwei Wege zur Auswahl. Die erste Option lädt dazu ein, die Reise ohne Unterstützung zu beginnen, während die zweite einen hilfreichen Leitfaden bietet, um den Erfolg sicherzustellen. Egal, ob du mutig eintauchst oder dem strukturierten Leitfaden folgst, erwartet dich ein faszinierendes Erlebnis, das mit einer funktionalen und fesselnden Konsolenanwendung endet.

Masterplan

  • Schritt 1: Einrichtung und Initialisierungen;
  • Schritt 2: Definition der Spielparameter;
  • Schritt 3: Definition von Hilfsfunktionen;
  • Schritt 4: Spiellogik;
  • Schritt 5: Speichern des Spielergebnisses;
  • Schritt 6: Spielstart;
  • Fazit;
  • Vollständiger App-Code.

Schritt 1: Einrichtung und Initialisierungen

Bereite die Arbeitsumgebung vor, indem du ein neues Verzeichnis und eine Datei namens app.js erstellst. In dieser Datei binden wir die benötigten Module ein:

const readline = require('readline');
const fs = require('fs').promises;

Erstellen einer Readline-Schnittstelle:

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});
Codebeschreibung
expand arrow
  • readline: bietet eine Schnittstelle zum Lesen von Eingaben und Schreiben von Ausgaben in die Konsole;

  • readline.createInterface({ ... }): erstellt eine Instanz der Klasse readline.Interface. Es akzeptiert ein Objekt mit den Eigenschaften input und output;

  • input: process.stdin: legt den Eingabestrom auf process.stdin fest, sodass das Programm Benutzereingaben von der Tastatur lesen kann;

  • output: process.stdout: legt den Ausgabestrom auf process.stdout fest, sodass das Programm Text in der Konsole anzeigen kann.

Erläuterung: Die erforderlichen Module werden importiert: readline für die Benutzerinteraktion und fs.promises für Dateioperationen. Anschließend wird eine Readline-Schnittstelle mit dem Namen rl erstellt, um Eingaben und Ausgaben zu verwalten.

Schritt 2: Spielparameter festlegen

Festlegen der minimalen und maximalen Zahlen:

const minNumber = 1;
const maxNumber = 100;

Das Geheimzahl generieren:

const secretNumber =
  Math.floor(Math.random() * (maxNumber - minNumber + 1)) + minNumber;
Codebeschreibung
expand arrow
  • Math.random(): erzeugt eine zufällige Fließkommazahl zwischen 0 (einschließlich) und 1 (ausschließlich);

  • maxNumber - minNumber + 1: berechnet den Bereich der möglichen Zahlen. Das Hinzufügen von 1 stellt sicher, dass sowohl minNumber als auch maxNumber im Bereich enthalten sind;

  • Math.random() * (maxNumber - minNumber + 1): erzeugt eine Zufallszahl zwischen 0 und dem berechneten Bereich;

  • Math.floor(...): rundet die erzeugte Fließkommazahl auf die nächstkleinere ganze Zahl ab, sodass das Ergebnis eine ganze Zahl im gewünschten Bereich ist;

  • ... + minNumber: verschiebt die erzeugte Zahl, sodass der Bereich bei minNumber statt bei 0 beginnt.

Initialisierung des Versuchszählers:

let attempts = 0;

Erläuterung: Der Zahlenbereich (minNumber und maxNumber), in dem die geheime Zahl generiert wird, wird definiert. Die geheime Zahl wird zufällig mit Math.random() erzeugt und der Variable secretNumber zugewiesen. Die Variable attempts wird initialisiert, um die Versuche des Benutzers zu zählen.

Schritt 3: Hilfsfunktionen definieren

Ausstattung mit einer Hilfsfunktion für eine einwandfreie Validierung:

function isValidGuess(guess) {
  return !isNaN(guess)
    && guess >= minNumber
    && guess <= maxNumber;
}
Codebeschreibung
expand arrow
  • !isNaN(guess): Prüft, ob guess eine gültige Zahl ist. Die Funktion isNaN() gibt für gültige Zahlen false zurück, und der Operator ! kehrt dies zu true um;

  • guess >= minNumber: Überprüft, ob guess größer oder gleich minNumber ist, um sicherzustellen, dass der Wert nicht unterhalb des erlaubten Bereichs liegt;

  • guess <= maxNumber: Überprüft, ob guess kleiner oder gleich maxNumber ist, um sicherzustellen, dass der Wert nicht oberhalb des erlaubten Bereichs liegt;

  • &&: Verknüpft alle Bedingungen mit dem logischen UND-Operator. Jede Bedingung muss true sein, damit der gesamte Ausdruck zu true ausgewertet wird.

Erläuterung: Die Funktion isValidGuess prüft, ob die Eingabe des Benutzers eine gültige Zahl innerhalb des angegebenen Bereichs (minNumber bis maxNumber) ist.

Schritt 4: Spiellogik

Die Kernmechanik des Spiels über die Funktion playGame:

function playGame() {
  rl.question(`Guess a number between ${minNumber} and ${maxNumber}: `, guess => {
    if (isValidGuess(guess)) {
      attempts++;
      const guessNumber = parseInt(guess);

      if (guessNumber === secretNumber) {
        console.log(`Congratulations! You guessed the number in ${attempts} attempts.`);
        saveGameResult(`Player won in ${attempts} attempts.`);
        rl.close();
      } else if (guessNumber < secretNumber) {
        console.log('Try higher.');
        playGame();
      } else {
        console.log('Try lower.');
        playGame();
      }
    } else {
      console.log('Please enter a valid number within the specified range.');
      playGame();
    }
  });
}
Codebeschreibung
expand arrow
  • rl.question(\Guess a number between ${minNumber} and ${maxNumber}: `, guess => { ... }): prompts the user to enter a number within the specified range. The user's input is passed to the callback function as the guess` an die Callback-Funktion übergeben;

  • if (isValidGuess(guess)) { ... }: Prüft, ob der eingegebene Wert mit der Funktion isValidGuess() eine gültige Zahl ist;

  • attempts++;: Erhöht den Zähler attempts, um die Anzahl der Versuche des Spielers zu verfolgen;

  • const guessNumber = parseInt(guess);: Wandelt die Benutzereingabe mit parseInt() von einem String in eine Ganzzahl um;

  • if (guessNumber === secretNumber) { ... }: Prüft, ob die Eingabe des Spielers mit der geheimen Zahl übereinstimmt. Falls ja, wird eine Erfolgsmeldung angezeigt, das Ergebnis gespeichert, das readline-Interface geschlossen und das Spiel beendet;

  • else if (guessNumber < secretNumber) { ... }: Informiert den Spieler, dass die geheime Zahl größer ist, und ruft erneut playGame() auf, um das Spiel fortzusetzen;

  • else { ... }: Informiert den Spieler, dass die geheime Zahl kleiner ist, und ruft erneut playGame() auf, um das Spiel fortzusetzen;

  • else { ... } (nach der Validierungsprüfung): Behandelt ungültige Eingaben, indem der Spieler aufgefordert wird, eine gültige Zahl im erlaubten Bereich einzugeben, und ruft anschließend erneut playGame() auf.

Erläuterung: Die Funktion playGame bildet die zentrale Spielschleife. Sie verwendet rl.question, um den Benutzer nach einer Schätzung zu fragen. Ist die Eingabe gültig, prüft die Funktion, ob die Schätzung mit der geheimen Zahl übereinstimmt. Andernfalls gibt sie dem Benutzer eine Rückmeldung und setzt die Spielschleife rekursiv fort.

Schritt 5: Spielergebnis speichern

Implementierung der Logik zum Speichern der Spielerfolge des Benutzers in der Datei game_results.txt.

async function saveGameResult(result) {
  try {
    await fs.appendFile('game_results.txt', `${result}\n`);
    console.log('Game result saved.');
  } catch (err) {
    console.log('Failed to save game result.');
  }
}
Codebeschreibung
expand arrow
  • async function saveGameResult(result) { ... }: definiert eine asynchrone Funktion namens saveGameResult(), die einen Parameter result akzeptiert und die Verwendung des await-Schlüsselworts im Funktionskörper ermöglicht;

  • try { ... } catch (err) { ... }: behandelt potenzielle Fehler, die während des asynchronen Dateioperation auftreten können;

  • await fs.appendFile('game_results.txt', \${result}\n`);: appends the provided resultfollowed by a newline character to thegame_results.txtfile. Theawait` pausiert die Ausführung, bis die Dateioperation erfolgreich abgeschlossen ist;

  • console.log('Game result saved.');: zeigt eine Bestätigungsmeldung an, wenn das Spielergebnis erfolgreich in die Datei geschrieben wurde;

  • console.log('Failed to save game result.');: zeigt eine Fehlermeldung an, falls die Dateioperation fehlschlägt und eine Ausnahme vom catch-Block abgefangen wird.

Erläuterung: Die Funktion saveGameResult verwendet fs.promises, um das Spielergebnis an eine Datei namens game_results.txt anzuhängen. Sie gibt eine Rückmeldung über den Erfolg oder Misserfolg beim Speichern des Ergebnisses.

Schritt 6: Spiel starten

Begrüßungsnachricht erstellen und das Spiel starten:

console.log('Welcome to the Guess the Number game!');
playGame();

Erläuterung: Es wird eine Begrüßungsnachricht angezeigt und die Spielschleife durch Aufruf der Funktion playGame gestartet.

Vollständiger App-Code

const readline = require("readline");
const fs = require("fs").promises;

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});

const minNumber = 1;
const maxNumber = 100;

const secretNumber =
  Math.floor(Math.random() * (maxNumber - minNumber + 1)) + minNumber;
let attempts = 0;

function isValidGuess(guess) {
  return !isNaN(guess) && guess >= minNumber && guess <= maxNumber;
}

function playGame() {
  rl.question(
    `Guess a number between ${minNumber} and ${maxNumber}: `,
    (guess) => {
      if (isValidGuess(guess)) {
        attempts++;
        const guessNumber = parseInt(guess);

        if (guessNumber === secretNumber) {
          console.log(
            `Congratulations! You guessed the number in ${attempts} attempts.`
          );
          saveGameResult(`Player won in ${attempts} attempts.`);
          rl.close();
        } else if (guessNumber < secretNumber) {
          console.log("Try higher.");
          playGame();
        } else {
          console.log("Try lower.");
          playGame();
        }
      } else {
        console.log("Please enter a valid number within the specified range.");
        playGame();
      }
    }
  );
}

async function saveGameResult(result) {
  try {
    await fs.appendFile("game_results.txt", `${result}\n`);
    console.log("Game result saved.");
  } catch (err) {
    console.log("Failed to save game result.");
  }
}

console.log("Welcome to the Guess the Number game!");
playGame();
Codebeschreibung
expand arrow
  • Zeilen 1-2: Import des eingebauten Moduls readline und der fs-API des promises-Moduls für asynchrone Dateioperationen;

  • Zeilen 4-7: Erstellung einer Readline-Schnittstelle namens rl zum Einlesen von Benutzereingaben und zur Anzeige von Ausgaben in der Konsole;

  • Zeilen 9-10: Definition der minimalen und maximalen Werte für den Zahlenbereich des Spiels;

  • Zeilen 12-13: Generierung einer zufälligen geheimen Zahl innerhalb des angegebenen Bereichs mit Math.random();

  • Zeile 14: Initialisierung des Zählers attempts, um die Anzahl der Versuche des Spielers zu verfolgen;

  • Zeilen 16-18: Definition der Funktion isValidGuess(), um zu prüfen, ob der eingegebene Wert eine Zahl im erlaubten Bereich ist;

  • Zeilen 20-47: Definition der rekursiven Funktion playGame(), die:

    • den Spieler auffordert, eine Zahl zu raten;
    • den eingegebenen Wert validiert;
    • prüft, ob die geratene Zahl der geheimen Zahl entspricht;
    • Rückmeldung gibt, ob die Zahl zu hoch oder zu niedrig ist;
    • das Spiel fortsetzt, indem sie sich selbst erneut aufruft, falls nötig;
    • das Ergebnis speichert und das Spiel beendet, wenn die richtige Zahl erraten wurde;
  • Zeilen 49-56: Definition der asynchronen Funktion saveGameResult(), die das Spielergebnis in die Datei game_results.txt speichert und mögliche Fehler behandelt;

  • Zeile 58: Anzeige einer Willkommensnachricht für den Spieler;

  • Zeile 59: Start des Spiels durch Aufruf der Funktion playGame().

Zusammenfassung

Dieses Programm erstellt ein Zahlenratespiel. Der Spieler versucht, eine zufällig generierte Zahl innerhalb eines vorgegebenen Bereichs zu erraten. Das Spiel gibt nach jedem Versuch eine Rückmeldung, zählt die Anzahl der Versuche und speichert erfolgreiche Ergebnisse mithilfe asynchroner Dateioperationen in einer Textdatei.

War alles klar?

Wie können wir es verbessern?

Danke für Ihr Feedback!

Abschnitt 2. Kapitel 8

Fragen Sie AI

expand

Fragen Sie AI

ChatGPT

Fragen Sie alles oder probieren Sie eine der vorgeschlagenen Fragen, um unser Gespräch zu beginnen

Abschnitt 2. Kapitel 8
some-alt