Creación de una Aplicación de Consola de Adivinanzas
Desliza para mostrar el menú
En este capítulo, prepárate para mejorar tus habilidades en aplicaciones de consola mientras exploramos la creación de un emocionante juego de Adivina el Número. Este juego interactivo desafía a los jugadores a poner a prueba su intuición adivinando un número generado aleatoriamente dentro de un rango predefinido. A lo largo del proceso, se abordarán conceptos fundamentales como:
- Generación de números aleatorios;
- Validación de entradas;
- Interacción con el usuario;
- Incluso guardar los resultados del juego en un archivo.
Desafío
Imagina sumergirte en una aplicación que promete emoción e intriga. Los jugadores están invitados a adivinar un número elegido misteriosamente dentro de un rango predefinido. La aplicación ofrece retroalimentación instantánea en cada intento y lleva un registro detallado de los intentos realizados.
Este ejemplo práctico es una oportunidad para perfeccionar habilidades en la construcción de aplicaciones CLI y demuestra el arte de crear programas interactivos.
Aplicación resultante
¡Observa la magia en acción! A continuación se muestra un GIF que ilustra la emocionante aplicación del juego Adivina el Número que estarás creando:
Creación de una aplicación de consola para un juego de adivinanzas
Se presentan dos caminos. La primera opción invita a embarcarse en el viaje sin ayuda, mientras que la segunda ofrece una guía útil para asegurar el éxito. Ya sea que te lances con valentía o sigas la guía estructurada, te espera una experiencia fascinante que te dejará con una aplicación de consola funcional y atractiva.
Plan maestro
- Paso 1: Configuración e inicializaciones;
- Paso 2: Definir los parámetros del juego;
- Paso 3: Definir funciones utilitarias;
- Paso 4: Lógica del juego;
- Paso 5: Guardar el resultado del juego;
- Paso 6: Iniciar el juego;
- Conclusión;
- Código completo de la aplicación.
Paso 1: Configuración e inicializaciones
Prepara el entorno creando un nuevo directorio y un archivo llamado app.js. Dentro de este archivo, incluimos los módulos necesarios:
const readline = require('readline');
const fs = require('fs').promises;
Crear una interfaz de Readline:
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
-
readline: proporciona una interfaz para leer la entrada y escribir la salida en la consola; -
readline.createInterface({ ... }): crea una instancia de la clasereadline.Interface. Acepta un objeto con las propiedadesinputyoutput; -
input: process.stdin: establece el flujo de entrada enprocess.stdin, permitiendo que el programa lea la entrada del usuario desde el teclado; -
output: process.stdout: establece el flujo de salida enprocess.stdout, permitiendo que el programa muestre texto en la consola.
Explicación: Se importan los módulos necesarios: readline para la interacción con el usuario y fs.promises para operaciones con archivos. Luego, se crea una interfaz Readline llamada rl para gestionar la entrada y salida.
Paso 2: Definir los parámetros del juego
Establecer los números mínimo y máximo:
const minNumber = 1;
const maxNumber = 100;
Generar el número secreto:
const secretNumber =
Math.floor(Math.random() * (maxNumber - minNumber + 1)) + minNumber;
-
Math.random(): genera un número aleatorio de punto flotante entre0(incluido) y1(excluido); -
maxNumber - minNumber + 1: calcula el rango de números posibles. Al sumar1se asegura que tantominNumbercomomaxNumberestén incluidos en el rango; -
Math.random() * (maxNumber - minNumber + 1): genera un número aleatorio entre0y el rango calculado; -
Math.floor(...): redondea el número de punto flotante generado hacia abajo al entero más cercano, asegurando que el resultado sea un número entero dentro del rango deseado; -
... + minNumber: desplaza el número generado para que el rango comience enminNumberen lugar de0.
Inicializar el contador de intentos:
let attempts = 0;
Explicación: Se define el rango de números (minNumber y maxNumber) dentro del cual se generará el número secreto. El número secreto se genera aleatoriamente utilizando Math.random() y se asigna a secretNumber. La variable attempts se inicializa para llevar el registro de los intentos del usuario.
Paso 3: Definir funciones utilitarias
Incorporación de una función utilitaria para una validación impecable:
function isValidGuess(guess) {
return !isNaN(guess)
&& guess >= minNumber
&& guess <= maxNumber;
}
-
!isNaN(guess): verifica siguesses un número válido. La funciónisNaN()devuelvefalsepara números válidos, y el operador!lo invierte atrue; -
guess >= minNumber: verifica queguesssea mayor o igual queminNumber, asegurando que no esté por debajo del rango permitido; -
guess <= maxNumber: verifica queguesssea menor o igual quemaxNumber, asegurando que no esté por encima del rango permitido; -
&&: combina todas las condiciones utilizando el operador lógico AND. Todas las condiciones deben sertruepara que la expresión completa se evalúe comotrue.
Explicación: La función isValidGuess verifica si la suposición del usuario es un número válido dentro del rango especificado (minNumber a maxNumber).
Paso 4: Lógica del juego
La mecánica central del juego a través de la función 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 si el valor ingresado es una suposición válida usando la funciónisValidGuess(); -
attempts++;: incrementa el contadorattemptspara registrar cuántos intentos ha realizado el jugador; -
const guessNumber = parseInt(guess);: convierte la entrada del usuario de cadena a entero usandoparseInt(); -
if (guessNumber === secretNumber) { ... }: verifica si la suposición del jugador coincide con el número secreto. Si es así, el juego muestra un mensaje de éxito, guarda el resultado, cierra la interfaz dereadliney finaliza el juego; -
else if (guessNumber < secretNumber) { ... }: informa al jugador que el número secreto es mayor y llama nuevamente aplayGame()para continuar el juego; -
else { ... }: informa al jugador que el número secreto es menor y llama nuevamente aplayGame()para continuar el juego; -
else { ... }(después de la validación): gestiona la entrada no válida solicitando al jugador que ingrese un número válido dentro del rango permitido y luego llama nuevamente aplayGame().
Explicación: La función playGame constituye el bucle principal del juego. Utiliza rl.question para solicitar al usuario una suposición. Si la suposición es válida, la función verifica si coincide con el número secreto. Si no es así, proporciona retroalimentación al usuario y continúa el bucle del juego de forma recursiva.
Paso 5: Guardar el resultado del juego
Implementación de la lógica para guardar los logros del usuario en el archivo 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) { ... }: define una función asíncrona llamadasaveGameResult()que acepta un parámetroresulty permite el uso de la palabra claveawaitdentro del cuerpo de la función; -
try { ... } catch (err) { ... }: gestiona posibles errores que pueden ocurrir durante la operación asíncrona de archivos; -
await fs.appendFile('game_results.txt', \${result}\n`);: appends the providedresultfollowed by a newline character to thegame_results.txtfile. Theawait` pausa la ejecución hasta que la operación de archivo se complete correctamente; -
console.log('Game result saved.');: muestra un mensaje de confirmación cuando el resultado del juego se escribe correctamente en el archivo; -
console.log('Failed to save game result.');: muestra un mensaje de error si la operación de archivo falla y una excepción es capturada por el bloquecatch.
Explicación: La función saveGameResult utiliza fs.promises para agregar el resultado del juego a un archivo llamado game_results.txt. Proporciona retroalimentación sobre el éxito o fallo al guardar el resultado.
Paso 6: Iniciar el juego
Crear el mensaje de bienvenida e iniciar el juego:
console.log('Welcome to the Guess the Number game!');
playGame();
Explicación: Se muestra un mensaje de bienvenida y se inicia el ciclo del juego llamando a la función playGame.
Código completo de la aplicación
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();
-
Líneas 1-2: importación del módulo incorporado
readliney la APIfsdel módulopromisespara operaciones de archivos asíncronas; -
Líneas 4-7: creación de una interfaz readline llamada
rlpara leer la entrada del usuario y mostrar la salida en la consola; -
Líneas 9-10: definición de los valores mínimo y máximo para el rango de adivinanza;
-
Líneas 12-13: generación de un número secreto aleatorio dentro del rango especificado usando
Math.random(); -
Línea 14: inicialización del contador
attemptspara registrar la cantidad de intentos realizados por el jugador; -
Líneas 16-18: definición de la función
isValidGuess()para validar que el valor ingresado sea un número dentro del rango permitido; -
Líneas 20-47: definición de la función recursiva
playGame()que:- solicita al jugador que ingrese un número;
- valida el valor ingresado;
- verifica si la adivinanza coincide con el número secreto;
- proporciona retroalimentación si la adivinanza es demasiado alta o baja;
- continúa el juego llamándose a sí misma cuando sea necesario;
- guarda el resultado y finaliza el juego cuando se adivina el número correcto;
-
Líneas 49-56: definición de la función asíncrona
saveGameResult()que guarda el resultado del juego en el archivogame_results.txty maneja posibles errores; -
Línea 58: muestra un mensaje de bienvenida al jugador;
-
Línea 59: inicia el juego llamando a la función
playGame().
Resumen
Este programa crea un juego de adivinanza de números. El jugador intenta adivinar un número generado aleatoriamente dentro de un rango especificado. El juego proporciona retroalimentación después de cada intento, registra la cantidad de intentos y guarda los resultados exitosos en un archivo de texto utilizando operaciones de archivos asíncronas.
¡Gracias por tus comentarios!
Pregunte a AI
Pregunte a AI
Pregunte lo que quiera o pruebe una de las preguntas sugeridas para comenzar nuestra charla