Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Lære Opbygning af et Gætteleg-Konsolprogram | Opbygning af Konsolapplikationer med Node.js
Backend-Udvikling med Node.js og Express.js

Opbygning af et Gætteleg-Konsolprogram

Stryg for at vise menuen

I dette kapitel får du mulighed for at forbedre dine færdigheder i at udvikle konsolapplikationer, når vi dykker ned i opbygningen af et spændende Gæt Tallet-spil. Dette interaktive spil udfordrer spillere til at bruge deres intuition ved at gætte et tilfældigt genereret tal inden for et foruddefineret interval. Undervejs udforsker vi grundlæggende begreber som:

  • Tilfældig talgenerering;
  • Validering af input;
  • Brugerinteraktion;
  • Endda gemme spilresultater i en fil.

Udfordring

Forestil dig at udforske en app, der lover spænding og mystik. Spillere inviteres til at gætte et hemmeligt valgt tal inden for et foruddefineret interval. Appen giver øjeblikkelig feedback på hvert gæt og holder nøje styr på antallet af forsøg.

Dette praktiske eksempel er din mulighed for at forfine dine færdigheder i at bygge CLI-apps og demonstrerer kunsten at skabe interaktive programmer.

Resultat App

Se magien udfolde sig! Nedenfor ses en GIF, der illustrerer det spændende Gæt Tallet-spil, som du skal bygge:

Bygning af et Gæt et Tal-konsolprogram

Du står over for to veje. Den første mulighed opfordrer dig til at begive dig ud på rejsen uden hjælp, mens den anden tilbyder en hjælpsom guide for at sikre din succes. Uanset om du kaster dig ud i det eller følger den strukturerede guide, venter der dig en fascinerende oplevelse, der vil efterlade dig med et funktionelt og fængende konsolprogram.

Masterplan

  • Trin 1: Opsætning og initialisering;
  • Trin 2: Definer spilparametre;
  • Trin 3: Definer hjælpefunktioner;
  • Trin 4: Spil-logik;
  • Trin 5: Gem spilresultat;
  • Trin 6: Start spillet;
  • Konklusion;
  • Fuld programkode.

Trin 1: Opsætning og initialisering

Forbered lærredet ved at oprette et nyt bibliotek og en fil med navnet app.js. I denne fil importeres de nødvendige moduler:

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

Opret et Readline-interface:

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});
Kodebeskrivelse
expand arrow
  • readline: giver en grænseflade til at læse input fra og skrive output til konsollen;

  • readline.createInterface({ ... }): opretter en instans af readline.Interface-klassen. Den accepterer et objekt med egenskaberne input og output;

  • input: process.stdin: sætter inputstrømmen til process.stdin, hvilket gør det muligt for programmet at læse brugerinput fra tastaturet;

  • output: process.stdout: sætter outputstrømmen til process.stdout, hvilket gør det muligt for programmet at vise tekst i konsollen.

Forklaring: Vi importerer de nødvendige moduler: readline til brugerinteraktion og fs.promises til filoperationer. Derefter opretter vi et Readline-interface kaldet rl til at håndtere input og output.

Trin 2: Definer spilparametre

Angiv minimums- og maksimumstal:

const minNumber = 1;
const maxNumber = 100;

Generér det hemmelige tal:

const secretNumber =
  Math.floor(Math.random() * (maxNumber - minNumber + 1)) + minNumber;
Kodebeskrivelse
expand arrow
  • Math.random(): genererer et tilfældigt flydende tal mellem 0 (inklusive) og 1 (eksklusive);

  • maxNumber - minNumber + 1: beregner intervallet af mulige tal. At lægge 1 til sikrer, at både minNumber og maxNumber er inkluderet i intervallet;

  • Math.random() * (maxNumber - minNumber + 1): genererer et tilfældigt tal mellem 0 og det beregnede interval;

  • Math.floor(...): afrunder det genererede flydende tal ned til nærmeste heltal, hvilket sikrer, at resultatet er et helt tal inden for det ønskede interval;

  • ... + minNumber: flytter det genererede tal, så intervallet starter ved minNumber i stedet for 0.

Initialiser tælleren for forsøg:

let attempts = 0;

Forklaring: Området for tal (minNumber og maxNumber) defineres, inden for hvilket det hemmelige tal genereres. Det hemmelige tal genereres tilfældigt ved hjælp af Math.random() og tildeles til secretNumber. Variablen attempts initialiseres for at holde styr på brugerens forsøg.

Trin 3: Definer hjælpefunktioner

Udstyret med en hjælpefunktion for fejlfri validering:

function isValidGuess(guess) {
  return !isNaN(guess)
    && guess >= minNumber
    && guess <= maxNumber;
}
Kodebeskrivelse
expand arrow
  • !isNaN(guess): kontrollerer om guess er et gyldigt tal. Funktionen isNaN() returnerer false for gyldige tal, og !-operatoren vender det til true;

  • guess >= minNumber: verificerer at guess er større end eller lig med minNumber, hvilket sikrer at det ikke er under det tilladte interval;

  • guess <= maxNumber: verificerer at guess er mindre end eller lig med maxNumber, hvilket sikrer at det ikke er over det tilladte interval;

  • &&: kombinerer alle betingelser ved hjælp af den logiske OG-operator. Alle betingelser skal være true for at hele udtrykket evalueres til true.

Forklaring: Funktionen isValidGuess kontrollerer, om brugerens gæt er et gyldigt tal inden for det angivne interval (minNumber til maxNumber).

Trin 4: Spillets logik

Spillets kernefunktionalitet gennem funktionen 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();
    }
  });
}
Kodebeskrivelse
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`;

  • if (isValidGuess(guess)) { ... }: kontrollerer, om den indtastede værdi er et gyldigt gæt ved hjælp af funktionen isValidGuess();

  • attempts++;: øger tælleren attempts for at holde styr på, hvor mange gæt spilleren har brugt;

  • const guessNumber = parseInt(guess);: konverterer brugerens input fra en streng til et heltal med parseInt();

  • if (guessNumber === secretNumber) { ... }: kontrollerer, om spillerens gæt matcher det hemmelige tal. Hvis det gør, vises en succesmeddelelse, resultatet gemmes, readline-interfacet lukkes, og spillet afsluttes;

  • else if (guessNumber < secretNumber) { ... }: informerer spilleren om, at det hemmelige tal er højere, og kalder playGame() igen for at fortsætte spillet;

  • else { ... }: informerer spilleren om, at det hemmelige tal er lavere, og kalder playGame() igen for at fortsætte spillet;

  • else { ... } (efter valideringskontrollen): håndterer ugyldigt input ved at bede spilleren indtaste et gyldigt tal inden for det tilladte interval og kalder derefter playGame() igen.

Forklaring: playGame-funktionen udgør den centrale spilsløjfe. Den bruger rl.question til at bede brugeren om et gæt. Hvis gættet er gyldigt, kontrollerer funktionen, om gættet matcher det hemmelige tal. Hvis ikke, gives der feedback til brugeren, og spilsløjfen fortsætter rekursivt.

Trin 5: Gem spilresultat

Implementering af logikken til at gemme brugerens spilpræstationer i filen 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.');
  }
}
Kodebeskrivelse
expand arrow
  • async function saveGameResult(result) { ... }: definerer en asynkron funktion ved navn saveGameResult(), som accepterer en parameter result og muliggør brugen af await-nøgleordet i funktionskroppen;

  • try { ... } catch (err) { ... }: håndterer potentielle fejl, der kan opstå under den asynkrone filoperation;

  • await fs.appendFile('game_results.txt', \${result}\n`);: appends the provided resultfollowed by a newline character to thegame_results.txtfile. Theawait`-nøgleordet pauser eksekveringen, indtil filoperationen er gennemført med succes;

  • console.log('Game result saved.');: viser en bekræftelsesbesked, når spilresultatet er skrevet til filen med succes;

  • console.log('Failed to save game result.');: viser en fejlmeddelelse, hvis filoperationen mislykkes, og en undtagelse opfanges af catch-blokken.

Forklaring: Funktionen saveGameResult bruger fs.promises til at tilføje spilresultatet til en fil med navnet game_results.txt. Den giver feedback om, hvorvidt det lykkedes at gemme resultatet eller ej.

Trin 6: Start spillet

Opret velkomstbeskeden og start spillet:

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

Forklaring: Vi viser en velkomstbesked og starter spil-loopet ved at kalde funktionen playGame.

Fuld app-kode

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();
Kodebeskrivelse
expand arrow
  • Linje 1-2: importerer det indbyggede readline-modul og fs-modulets promises API til asynkrone filoperationer;

  • Linje 4-7: opretter et readline-interface kaldet rl til at læse brugerinput og vise output i konsollen;

  • Linje 9-10: definerer minimums- og maksimumsværdierne for gætterækken;

  • Linje 12-13: genererer et tilfældigt hemmeligt tal inden for det angivne interval ved hjælp af Math.random();

  • Linje 14: initialiserer tælleren attempts til at holde styr på antallet af gæt foretaget af spilleren;

  • Linje 16-18: definerer funktionen isValidGuess() til at validere, at den indtastede værdi er et tal inden for det tilladte interval;

  • Linje 20-47: definerer den rekursive funktion playGame(), som:

    • beder spilleren om at indtaste et gæt;
    • validerer den indtastede værdi;
    • tjekker om gættet matcher det hemmelige tal;
    • giver feedback, hvis gættet er for højt eller for lavt;
    • fortsætter spillet ved at kalde sig selv igen, når det er nødvendigt;
    • gemmer resultatet og afslutter spillet, når det rigtige tal er gættet;
  • Linje 49-56: definerer den asynkrone funktion saveGameResult(), som gemmer spillets resultat i filen game_results.txt og håndterer potentielle fejl;

  • Linje 58: viser en velkomstbesked til spilleren;

  • Linje 59: starter spillet ved at kalde funktionen playGame().

Resumé

Dette program opretter et talgætspil. Spilleren forsøger at gætte et tilfældigt genereret tal inden for et angivet interval. Spillet giver feedback efter hvert gæt, tæller antallet af forsøg og gemmer succesfulde resultater i en tekstfil ved hjælp af asynkrone filoperationer.

Var alt klart?

Hvordan kan vi forbedre det?

Tak for dine kommentarer!

Sektion 2. Kapitel 8

Spørg AI

expand

Spørg AI

ChatGPT

Spørg om hvad som helst eller prøv et af de foreslåede spørgsmål for at starte vores chat

Sektion 2. Kapitel 8
some-alt