Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Lære Bygge en Gjettelek-Konsollapp | Bygge Konsollapplikasjoner med Node.js
Backend-Utvikling med Node.js og Express.js

Bygge en Gjettelek-Konsollapp

Sveip for å vise menyen

I dette kapittelet får du muligheten til å forbedre ferdighetene dine med konsollapplikasjoner når vi går i gang med å lage et spennende Gjett tallet-spill. Dette interaktive spillet utfordrer spillere til å bruke intuisjonen sin ved å gjette et tilfeldig generert tall innenfor et forhåndsdefinert område. Underveis utforsker vi grunnleggende konsepter som:

  • Generering av tilfeldige tall;
  • Validering av inndata;
  • Brukerinteraksjon;
  • Til og med lagring av spillresultater til en fil.

Utfordring

Se for deg å utforske en app som lover spenning og nysgjerrighet. Spillere inviteres til å gjette et mystisk valgt tall innenfor et forhåndsdefinert område. Appen gir umiddelbar tilbakemelding på hvert forsøk og holder nøye oversikt over antall forsøk.

Dette praktiske eksempelet gir deg muligheten til å videreutvikle ferdighetene dine i å bygge CLI-apper og viser hvordan man lager interaktive programmer.

Ferdig app

Se magien i praksis! Under ser du en GIF som illustrerer det spennende Gjett tallet-spillet du skal lage:

Bygge et konsollspill for gjettelek

Du står overfor to veier. Det første alternativet inviterer deg til å starte reisen uten hjelp, mens det andre tilbyr en nyttig veiledning for å sikre suksess. Enten du kaster deg ut i det eller følger den strukturerte veiledningen, venter en spennende opplevelse som gir deg en funksjonell og engasjerende konsollapplikasjon.

Hovedplan

  • Steg 1: Oppsett og initialisering;
  • Steg 2: Definer spillparametere;
  • Steg 3: Definer hjelpefunksjoner;
  • Steg 4: Spilllogikk;
  • Steg 5: Lagre spillresultat;
  • Steg 6: Start spillet;
  • Konklusjon;
  • Full app-kode.

Steg 1: Oppsett og initialisering

Forbered arbeidsområdet ved å opprette en ny mappe og en fil kalt app.js. I denne filen importerer vi nødvendige moduler:

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

Opprett et Readline-grensesnitt:

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});
Kodebeskrivelse
expand arrow
  • readline: gir et grensesnitt for å lese inn data fra og skrive ut data til konsollen;

  • readline.createInterface({ ... }): oppretter en instans av klassen readline.Interface. Den tar et objekt med egenskapene input og output;

  • input: process.stdin: setter inndatastrømmen til process.stdin, slik at programmet kan lese brukerinput fra tastaturet;

  • output: process.stdout: setter utdatastrømmen til process.stdout, slik at programmet kan vise tekst i konsollen.

Forklaring: Vi importerer nødvendige moduler: readline for brukerinteraksjon og fs.promises for filoperasjoner. Deretter oppretter vi et Readline-grensesnitt kalt rl for å håndtere inn- og utdata.

Steg 2: Definer spillparametere

Angi minimums- og maksimumstall:

const minNumber = 1;
const maxNumber = 100;

Generer det hemmelige tallet:

const secretNumber =
  Math.floor(Math.random() * (maxNumber - minNumber + 1)) + minNumber;
Kodebeskrivelse
expand arrow
  • Math.random(): genererer et tilfeldig flyttall mellom 0 (inkludert) og 1 (ekskludert);

  • maxNumber - minNumber + 1: beregner området for mulige tall. Å legge til 1 sikrer at både minNumber og maxNumber er inkludert i området;

  • Math.random() * (maxNumber - minNumber + 1): genererer et tilfeldig tall mellom 0 og det beregnede området;

  • Math.floor(...): runder det genererte flyttallet ned til nærmeste heltall, slik at resultatet blir et heltall innenfor ønsket område;

  • ... + minNumber: flytter det genererte tallet slik at området starter på minNumber i stedet for 0.

Initialiser forsøkstelleren:

let attempts = 0;

Forklaring: Vi definerer området for tallene (minNumber og maxNumber) som det hemmelige tallet skal genereres innenfor. Det hemmelige tallet genereres tilfeldig ved hjelp av Math.random() og tildeles secretNumber. Variabelen attempts initialiseres for å holde oversikt over brukerens forsøk.

Steg 3: Definer hjelpefunksjoner

Utstyr med en hjelpefunksjon for feilfri validering:

function isValidGuess(guess) {
  return !isNaN(guess)
    && guess >= minNumber
    && guess <= maxNumber;
}
Kodebeskrivelse
expand arrow
  • !isNaN(guess): sjekker om guess er et gyldig tall. Funksjonen isNaN() returnerer false for gyldige tall, og !-operatoren snur dette til true;

  • guess >= minNumber: verifiserer at guess er større enn eller lik minNumber, og sikrer at det ikke er under det tillatte området;

  • guess <= maxNumber: verifiserer at guess er mindre enn eller lik maxNumber, og sikrer at det ikke er over det tillatte området;

  • &&: kombinerer alle betingelsene ved hjelp av den logiske OG-operatoren. Alle betingelsene må være true for at hele uttrykket skal evalueres til true.

Forklaring: Funksjonen isValidGuess sjekker om brukerens gjetning er et gyldig tall innenfor det angitte området (minNumber til maxNumber).

Steg 4: Spilllogikk

Spillets kjernefunksjonalitet gjennom playGame-funksjonen:

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)) { ... }: sjekker om den innskrevne verdien er en gyldig gjetning ved å bruke funksjonen isValidGuess();

  • attempts++;: øker telleren attempts for å holde oversikt over hvor mange forsøk spilleren har brukt;

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

  • if (guessNumber === secretNumber) { ... }: sjekker om spillerens gjetning samsvarer med det hemmelige tallet. Hvis det stemmer, vises en suksessmelding, resultatet lagres, readline-grensesnittet lukkes, og spillet avsluttes;

  • else if (guessNumber < secretNumber) { ... }: informerer spilleren om at det hemmelige tallet er høyere og kaller playGame() på nytt for å fortsette spillet;

  • else { ... }: informerer spilleren om at det hemmelige tallet er lavere og kaller playGame() på nytt for å fortsette spillet;

  • else { ... } (etter valideringssjekken): håndterer ugyldig input ved å be spilleren skrive inn et gyldig tall innenfor det tillatte området og kaller deretter playGame() på nytt.

Forklaring: playGame-funksjonen utgjør kjernen i spill-løkken. Den bruker rl.question for å be brukeren om et gjett. Hvis gjettet er gyldig, sjekker funksjonen om gjettet samsvarer med det hemmelige tallet. Hvis ikke, gir den tilbakemelding til brukeren og fortsetter spill-løkken rekursivt.

Steg 5: Lagre spillresultat

Implementering av logikken for å lagre brukerens spillprestasjoner 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 funksjon kalt saveGameResult() som tar imot en result-parameter og tillater bruk av await-nøkkelordet inne i funksjonsblokken;

  • try { ... } catch (err) { ... }: håndterer potensielle feil som kan oppstå under den asynkrone filoperasjonen;

  • await fs.appendFile('game_results.txt', \${result}\n`);: appends the provided resultfollowed by a newline character to thegame_results.txtfile. Theawait`-nøkkelordet pauser utførelsen til filoperasjonen er fullført;

  • console.log('Game result saved.');: viser en bekreftelsesmelding når spillresultatet er skrevet til filen;

  • console.log('Failed to save game result.');: viser en feilmelding hvis filoperasjonen mislykkes og et unntak fanges opp av catch-blokken.

Forklaring: saveGameResult-funksjonen bruker fs.promises til å legge til spillresultatet i en fil kalt game_results.txt. Den gir tilbakemelding om det lyktes eller mislyktes å lagre resultatet.

Steg 6: Start spillet

Vis velkomstmelding og start spillet:

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

Forklaring: Vi viser en velkomstmelding og starter spill-løkken ved å kalle playGame-funksjonen.

Full 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();
Kodebeskrivelse
expand arrow
  • Linje 1-2: importerer det innebygde readline-modulet og fs-modulets promises-API for asynkrone filoperasjoner;

  • Linje 4-7: oppretter et readline-grensesnitt kalt rl for å lese brukerinput og vise utdata i konsollen;

  • Linje 9-10: definerer minimums- og maksimumsverdier for gjetteområdet;

  • Linje 12-13: genererer et tilfeldig hemmelig tall innenfor det angitte området ved hjelp av Math.random();

  • Linje 14: initialiserer attempts-teller for å holde oversikt over antall gjetninger spilleren har gjort;

  • Linje 16-18: definerer funksjonen isValidGuess() for å validere at den oppgitte verdien er et tall innenfor det tillatte området;

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

    • ber spilleren om å skrive inn et gjett;
    • validerer den oppgitte verdien;
    • sjekker om gjetningen samsvarer med det hemmelige tallet;
    • gir tilbakemelding hvis gjetningen er for høy eller for lav;
    • fortsetter spillet ved å kalle seg selv igjen ved behov;
    • lagrer resultatet og avslutter spillet når riktig tall er gjettet;
  • Linje 49-56: definerer den asynkrone funksjonen saveGameResult() som lagrer spillresultatet til filen game_results.txt og håndterer eventuelle feil;

  • Linje 58: viser en velkomstmelding til spilleren;

  • Linje 59: starter spillet ved å kalle funksjonen playGame().

Sammendrag

Dette programmet lager et tallgjettingsspill. Spilleren forsøker å gjette et tilfeldig generert tall innenfor et angitt område. Spillet gir tilbakemelding etter hver gjetning, holder oversikt over antall forsøk, og lagrer vellykkede resultater til en tekstfil ved hjelp av asynkrone filoperasjoner.

Alt var klart?

Hvordan kan vi forbedre det?

Takk for tilbakemeldingene dine!

Seksjon 2. Kapittel 8

Spør AI

expand

Spør AI

ChatGPT

Spør om hva du vil, eller prøv ett av de foreslåtte spørsmålene for å starte chatten vår

Seksjon 2. Kapittel 8
some-alt