Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Impara Creazione di un'App Console per il Gioco dell'Indovinello | Creazione di Applicazioni Console con Node.js
Sviluppo Backend con Node.js ed Express.js

Creazione di un'App Console per il Gioco dell'Indovinello

Scorri per mostrare il menu

In questo capitolo, preparati a migliorare le tue competenze nello sviluppo di applicazioni console mentre ci immergiamo nella creazione di un entusiasmante gioco Indovina il Numero. Questo gioco interattivo metterà alla prova l'intuizione dei giocatori, che dovranno indovinare un numero generato casualmente all'interno di un intervallo predefinito. Durante il percorso, esploreremo i concetti fondamentali come:

  • Generazione di numeri casuali;
  • Validazione dell'input;
  • Interazione con l'utente;
  • Salvataggio dei risultati di gioco su un file.

Sfida

Immagina di immergerti in un'app che promette emozione e mistero. I giocatori sono invitati a indovinare un numero scelto misteriosamente all'interno di un intervallo predefinito. L'app offre un feedback immediato per ogni tentativo e tiene un conteggio accurato delle prove effettuate.

Questo esempio pratico è l'occasione perfetta per affinare le tue competenze nella creazione di applicazioni CLI e mostra l'arte di realizzare programmi interattivi.

App finale

Guarda la magia in azione! Di seguito trovi una GIF che illustra l'entusiasmante gioco Indovina il Numero che andrai a realizzare:

Creazione di un'app console per il gioco dell'indovinello

Ti vengono presentati due percorsi. La prima opzione ti invita a intraprendere il viaggio senza assistenza, mentre la seconda offre una guida utile per assicurare il successo. Che tu scelga di tuffarti con audacia o di seguire la guida strutturata, vivrai un'esperienza affascinante che ti porterà a realizzare un'app console funzionale e coinvolgente.

Piano principale

  • Passo 1: Configurazione e inizializzazioni;
  • Passo 2: Definizione dei parametri di gioco;
  • Passo 3: Definizione delle funzioni di utilità;
  • Passo 4: Logica di gioco;
  • Passo 5: Salvataggio del risultato di gioco;
  • Passo 6: Avvio del gioco;
  • Conclusione;
  • Codice completo dell'app.

Passo 1: Configurazione e inizializzazioni

Prepara il contesto creando una nuova directory e un file chiamato app.js. All'interno di questo file, importiamo i moduli necessari:

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

Crea un'interfaccia Readline:

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});
Descrizione del codice
expand arrow
  • readline: fornisce un'interfaccia per leggere l'input e scrivere l'output sulla console;

  • readline.createInterface({ ... }): crea un'istanza della classe readline.Interface. Accetta un oggetto con le proprietà input e output;

  • input: process.stdin: imposta il flusso di input su process.stdin, consentendo al programma di leggere l'input dell'utente dalla tastiera;

  • output: process.stdout: imposta il flusso di output su process.stdout, consentendo al programma di visualizzare testo nella console.

Spiegazione: Importiamo i moduli necessari: readline per l'interazione con l'utente e fs.promises per le operazioni sui file. Successivamente, creiamo un'interfaccia Readline chiamata rl per gestire input e output.

Passaggio 2: Definizione dei parametri di gioco

Impostare i numeri minimo e massimo:

const minNumber = 1;
const maxNumber = 100;

Generazione del numero segreto:

const secretNumber =
  Math.floor(Math.random() * (maxNumber - minNumber + 1)) + minNumber;
Descrizione del codice
expand arrow
  • Math.random(): genera un numero in virgola mobile casuale compreso tra 0 (incluso) e 1 (escluso);

  • maxNumber - minNumber + 1: calcola l'intervallo dei numeri possibili. L'aggiunta di 1 garantisce che sia minNumber che maxNumber siano inclusi nell'intervallo;

  • Math.random() * (maxNumber - minNumber + 1): genera un numero casuale tra 0 e l'intervallo calcolato;

  • Math.floor(...): arrotonda per difetto il numero generato, assicurando che il risultato sia un numero intero all'interno dell'intervallo desiderato;

  • ... + minNumber: sposta il numero generato in modo che l'intervallo inizi da minNumber invece che da 0.

Inizializzazione del contatore dei tentativi:

let attempts = 0;

Spiegazione: Si definisce l'intervallo di numeri (minNumber e maxNumber) all'interno del quale verrà generato il numero segreto. Il numero segreto viene generato casualmente utilizzando Math.random() e assegnato a secretNumber. La variabile attempts viene inizializzata per tenere traccia dei tentativi dell'utente.

Passaggio 3: Definizione delle funzioni di utilità

Dotazione di una funzione di utilità per una validazione impeccabile:

function isValidGuess(guess) {
  return !isNaN(guess)
    && guess >= minNumber
    && guess <= maxNumber;
}
Descrizione del codice
expand arrow
  • !isNaN(guess): verifica se guess è un numero valido. La funzione isNaN() restituisce false per i numeri validi e l'operatore ! lo inverte in true;

  • guess >= minNumber: verifica che guess sia maggiore o uguale a minNumber, assicurando che non sia inferiore all'intervallo consentito;

  • guess <= maxNumber: verifica che guess sia minore o uguale a maxNumber, assicurando che non sia superiore all'intervallo consentito;

  • &&: combina tutte le condizioni utilizzando l'operatore logico AND. Ogni condizione deve essere true affinché l'espressione complessiva sia valutata come true.

Spiegazione: La funzione isValidGuess verifica se il tentativo dell'utente è un numero valido compreso nell'intervallo specificato (minNumber a maxNumber).

Passaggio 4: Logica del gioco

Le meccaniche principali del gioco tramite la funzione 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();
    }
  });
}
Descrizione del codice
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)) { ... }: verifica se il valore inserito è un tentativo valido utilizzando la funzione isValidGuess();

  • attempts++;: incrementa il contatore attempts per tenere traccia di quanti tentativi ha effettuato il giocatore;

  • const guessNumber = parseInt(guess);: converte l'input dell'utente da stringa a intero utilizzando parseInt();

  • if (guessNumber === secretNumber) { ... }: verifica se il tentativo del giocatore corrisponde al numero segreto. In caso affermativo, il gioco mostra un messaggio di successo, salva il risultato, chiude l'interfaccia readline e termina la partita;

  • else if (guessNumber < secretNumber) { ... }: informa il giocatore che il numero segreto è più alto e richiama playGame() per continuare la partita;

  • else { ... }: informa il giocatore che il numero segreto è più basso e richiama playGame() per continuare la partita;

  • else { ... } (dopo il controllo di validazione): gestisce l'input non valido chiedendo al giocatore di inserire un numero valido nell'intervallo consentito e poi richiama nuovamente playGame().

Spiegazione: La funzione playGame costituisce il ciclo principale del gioco. Utilizza rl.question per chiedere all'utente di inserire un tentativo. Se il tentativo è valido, la funzione verifica se il tentativo corrisponde al numero segreto. In caso contrario, fornisce un feedback all'utente e continua ricorsivamente il ciclo del gioco.

Passaggio 5: Salvataggio del risultato del gioco

Implementazione della logica per salvare i risultati ottenuti dall'utente nel file 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.');
  }
}
Descrizione del codice
expand arrow
  • async function saveGameResult(result) { ... }: definisce una funzione asincrona chiamata saveGameResult() che accetta un parametro result e consente l'utilizzo della parola chiave await all'interno del corpo della funzione;

  • try { ... } catch (err) { ... }: gestisce eventuali errori che possono verificarsi durante l'operazione asincrona sul file;

  • await fs.appendFile('game_results.txt', \${result}\n`);: appends the provided resultfollowed by a newline character to thegame_results.txtfile. Theawait` sospende l'esecuzione fino al completamento dell'operazione sul file;

  • console.log('Game result saved.');: visualizza un messaggio di conferma quando il risultato del gioco viene scritto correttamente nel file;

  • console.log('Failed to save game result.');: visualizza un messaggio di errore se l'operazione sul file fallisce e viene intercettata un'eccezione dal blocco catch.

Spiegazione: La funzione saveGameResult utilizza fs.promises per aggiungere il risultato della partita a un file chiamato game_results.txt. Fornisce un feedback sul successo o il fallimento del salvataggio del risultato.

Passaggio 6: Avvio del gioco

Creazione del messaggio di benvenuto e avvio del gioco:

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

Spiegazione: Viene visualizzato un messaggio di benvenuto e si avvia il ciclo di gioco chiamando la funzione playGame.

Codice Completo dell'Applicazione

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();
Descrizione del codice
expand arrow
  • Righe 1-2: importazione del modulo integrato readline e dell'API fs del modulo promises per operazioni asincrone sui file;

  • Righe 4-7: creazione di un'interfaccia readline chiamata rl per leggere l'input dell'utente e mostrare l'output nella console;

  • Righe 9-10: definizione dei valori minimo e massimo per l'intervallo di numeri da indovinare;

  • Righe 12-13: generazione di un numero segreto casuale all'interno dell'intervallo specificato utilizzando Math.random();

  • Riga 14: inizializzazione del contatore attempts per tracciare il numero di tentativi effettuati dal giocatore;

  • Righe 16-18: definizione della funzione isValidGuess() per validare che il valore inserito sia un numero compreso nell'intervallo consentito;

  • Righe 20-47: definizione della funzione ricorsiva playGame() che:

    • richiede al giocatore di inserire un tentativo;
    • valida il valore inserito;
    • verifica se il tentativo corrisponde al numero segreto;
    • fornisce un feedback se il tentativo è troppo alto o troppo basso;
    • continua il gioco richiamando sé stessa quando necessario;
    • salva il risultato e termina il gioco quando viene indovinato il numero corretto;
  • Righe 49-56: definizione della funzione asincrona saveGameResult() che salva il risultato della partita nel file game_results.txt e gestisce eventuali errori;

  • Riga 58: visualizzazione di un messaggio di benvenuto per il giocatore;

  • Riga 59: avvio del gioco tramite la chiamata della funzione playGame().

Sintesi

Questo programma crea un gioco di indovinare il numero. Il giocatore tenta di indovinare un numero generato casualmente all'interno di un intervallo specificato. Il gioco fornisce un feedback dopo ogni tentativo, tiene traccia del numero di tentativi e salva i risultati vincenti in un file di testo utilizzando operazioni asincrone sui file.

Tutto è chiaro?

Come possiamo migliorarlo?

Grazie per i tuoi commenti!

Sezione 2. Capitolo 8

Chieda ad AI

expand

Chieda ad AI

ChatGPT

Chieda pure quello che desidera o provi una delle domande suggerite per iniziare la nostra conversazione

Sezione 2. Capitolo 8
some-alt