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
});
-
readline: fornisce un'interfaccia per leggere l'input e scrivere l'output sulla console; -
readline.createInterface({ ... }): crea un'istanza della classereadline.Interface. Accetta un oggetto con le proprietàinputeoutput; -
input: process.stdin: imposta il flusso di input suprocess.stdin, consentendo al programma di leggere l'input dell'utente dalla tastiera; -
output: process.stdout: imposta il flusso di output suprocess.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;
-
Math.random(): genera un numero in virgola mobile casuale compreso tra0(incluso) e1(escluso); -
maxNumber - minNumber + 1: calcola l'intervallo dei numeri possibili. L'aggiunta di1garantisce che siaminNumberchemaxNumbersiano inclusi nell'intervallo; -
Math.random() * (maxNumber - minNumber + 1): genera un numero casuale tra0e 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 daminNumberinvece che da0.
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;
}
-
!isNaN(guess): verifica seguessè un numero valido. La funzioneisNaN()restituiscefalseper i numeri validi e l'operatore!lo inverte intrue; -
guess >= minNumber: verifica cheguesssia maggiore o uguale aminNumber, assicurando che non sia inferiore all'intervallo consentito; -
guess <= maxNumber: verifica cheguesssia minore o uguale amaxNumber, assicurando che non sia superiore all'intervallo consentito; -
&&: combina tutte le condizioni utilizzando l'operatore logico AND. Ogni condizione deve esseretrueaffinché l'espressione complessiva sia valutata cometrue.
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();
}
});
}
-
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 theguess`; -
if (isValidGuess(guess)) { ... }: verifica se il valore inserito è un tentativo valido utilizzando la funzioneisValidGuess(); -
attempts++;: incrementa il contatoreattemptsper tenere traccia di quanti tentativi ha effettuato il giocatore; -
const guessNumber = parseInt(guess);: converte l'input dell'utente da stringa a intero utilizzandoparseInt(); -
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'interfacciareadlinee termina la partita; -
else if (guessNumber < secretNumber) { ... }: informa il giocatore che il numero segreto è più alto e richiamaplayGame()per continuare la partita; -
else { ... }: informa il giocatore che il numero segreto è più basso e richiamaplayGame()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 nuovamenteplayGame().
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.');
}
}
-
async function saveGameResult(result) { ... }: definisce una funzione asincrona chiamatasaveGameResult()che accetta un parametroresulte consente l'utilizzo della parola chiaveawaitall'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 providedresultfollowed 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 bloccocatch.
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();
-
Righe 1-2: importazione del modulo integrato
readlinee dell'APIfsdel modulopromisesper operazioni asincrone sui file; -
Righe 4-7: creazione di un'interfaccia readline chiamata
rlper 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
attemptsper 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 filegame_results.txte 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.
Grazie per i tuoi commenti!
Chieda ad AI
Chieda ad AI
Chieda pure quello che desidera o provi una delle domande suggerite per iniziare la nostra conversazione