El juego Mastermind en Java trata de hacer una implementación, por consola, de un juego del mismo nombre pero con algunas modificaciones. Es algo así:
Realizar el juego en Java por consola en donde el programa piense una contraseña aleatoria (el usuario puede elegir si la misma puede o no contener repetidos, la clave serán dígitos del 0 al 9) y el usuario trate de adivinarla.
Si el usuario no acierta, el programa debe dar pistas por cada dígito de la contraseña:
*
como pista_
Cuando el usuario acierte la contraseña se debe indicar el número de intentos.
Veamos cómo implementar este juego en Mastermind en Java; será muy fácil y entretenido.
Comencemos viendo el método que va a generar la contraseña aleatoria que el usuario debe adivinar. Se ve así:
private static String obtenerPasswordAleatoria(boolean conRepetidos, int longitud) {
String muestra = "0123456789";
Random random = new Random(System.currentTimeMillis());
String pass = "";
for (int x = 0; x < longitud; x++) {
// Tomamos un dígito aleatorio
int indiceAleatorio = random.nextInt(muestra.length());
char digitoAleatorio = muestra.charAt(indiceAleatorio);
// Si no quieren repetidos...
if (!conRepetidos) {
// Mientras que en la cadena ya exista el carácter que acabamos de generar
while (pass.indexOf(digitoAleatorio) != -1) {
// Generamos otro
indiceAleatorio = random.nextInt(muestra.length());
digitoAleatorio = muestra.charAt(indiceAleatorio);
}
}
// De cualquier forma, agregamos el dígito a la cadena
pass += digitoAleatorio;
}
return pass;
}
Es una función que recibe un parámetro indicando si la contraseña debería contener repetidos, en caso de que no, generamos un nuevo carácter aleatorio mientras ese ya exista.
Como ves, la cadena aleatoria solo tendrá dígitos del 0 al 9 según la muestra de la línea 2.
El método también recibe un argumento indicando la longitud deseada de la contraseña.
Ahora veamos los métodos que sirven para obtener las preferencias del usuario. En primer lugar vamos a preguntarle si la contraseña puede contener caracteres repetidos.
En segundo lugar vamos a ver un método para obtener la suposición del usuario, es decir, la contraseña que cree que es.
Para todo esto vamos a usar un Scanner en Java.
private static String obtenerSuposicionDeUsuario(int longitud) {
String eleccion = "";
while (eleccion.length() != longitud) {
System.out.println("¿Cuál crees que es la contraseña?: ");
Scanner sc = new Scanner(System.in);
eleccion = sc.nextLine();
}
return eleccion;
}
private static boolean obtenerConRepetidos() {
System.out.println("¿Puede incluir repetidos? 1 = sí. 0 = no ");
return new Scanner(System.in).nextInt() == 1;
}
Estamos separando todo en métodos así la programación será más sencilla.
Otro método importante es aquel para obtener las pistas y mostrarlas al usuario, es decir, obtener una cadena que tendrá un asterisco, guión bajo o espacio en blanco.
Para ello he diseñado el siguiente método que recibe la contraseña original y verifica. Al inicio declaro una cadena vacía que contendrá las pistas; después simplemente recorro la cadena y compruebo las tres opciones posibles:
private static String obtenerPistas(String suposicionPassword, String passwordCorrecto) {
String pistas = "";
for (int x = 0; x < suposicionPassword.length(); x++) {
// Si está en el lugar correcto se indica con un *
if (suposicionPassword.charAt(x) == passwordCorrecto.charAt(x)) {
pistas += "*";
continue;
}
// Si está en la cadena pero no en el lugar correcto, se indica con un _
int indiceCaracter = passwordCorrecto.indexOf(suposicionPassword.charAt(x));
if (indiceCaracter != -1) {
pistas += "_";
continue;
}
// Finalmente, si ninguna de las condiciones de arriba se cumple, el carácter no
// está
pistas += " ";
}
return pistas;
}
De este modo al final tendremos una cadena con pistas.
Y finalmente veamos cómo se hace el loop o ciclo para jugar, además de los intentos en el método Main:
public static void main(String[] args) {
String menu = "¡Bienvenido! el programa va a pensar una contraseña de 5 dígitos y tú vas a intentar adivinarla\n"
+ "Si no aciertas: \nel programa te va a indicar con un * (asterisco) que el número que pusiste está en la posición correcta\n"
+ "Si es un _ (guión bajo) significa que el número está presente en la contraseña, pero va en una distinta posición\n"
+ "Si es un ' ' (espacio en blanco) significa que el número no está presente en la contraseña\n";
// Imprimir menú
System.out.println(menu);
int longitud = 5; // Longitud de la contraseña
// Saber si usuario quiere repetidos
boolean conRepetidos = obtenerConRepetidos();
String passwordCorrecto = obtenerPasswordAleatoria(conRepetidos, longitud);
int intentos = 1;
while (true) {// Ciclo infinito; se rompe cuando el usuario acierta con "break"
String suposicionUsuario = obtenerSuposicionDeUsuario(longitud);
if (suposicionUsuario.equals(passwordCorrecto)) {
System.out.printf("Ganaste en %d intentos\n", intentos);
break;
}
String pistas = obtenerPistas(suposicionUsuario, passwordCorrecto);
System.out.printf("Incorrecto. Pistas:\n%s\n", pistas);
intentos++;
}
}
Utilizamos los métodos mencionados anteriormente y hacemos un ciclo infinito en la línea 13. Después, comprobamos si lo que el usuario ingresó coincide con la contraseña usando el método equals en Java.
Cuando el usuario acierta, se indican los intentos. En caso de que no acierte, se suma el número de intentos y se vuelven a obtener las pistas para la suposición que fue brindada por el usuario,
Ahora veamos el código completo poniendo juntos todos los métodos. Queda como se ve a continuación:
/*
Programado por Luis Cabrera Benito
____ _____ _ _ _
| _ \ | __ \ (_) | | |
| |_) |_ _ | |__) |_ _ _ __ _____| |__ _ _| |_ ___
| _ <| | | | | ___/ _` | '__|_ / | '_ \| | | | __/ _ \
| |_) | |_| | | | | (_| | | / /| | |_) | |_| | || __/
|____/ \__, | |_| \__,_|_| /___|_|_.__/ \__, |\__\___|
__/ | __/ |
|___/ |___/
Blog: https://parzibyte.me/blog
Ayuda: https://parzibyte.me/blog/contrataciones-ayuda/
Contacto: https://parzibyte.me/blog/contacto/
*/import java.util.InputMismatchException;
import java.util.Random;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
String menu = "¡Bienvenido! el programa va a pensar una contraseña de 5 dígitos y tú vas a intentar adivinarla\n"
+ "Si no aciertas: \nel programa te va a indicar con un * (asterisco) que el número que pusiste está en la posición correcta\n"
+ "Si es un _ (guión bajo) significa que el número está presente en la contraseña, pero va en una distinta posición\n"
+ "Si es un ' ' (espacio en blanco) significa que el número no está presente en la contraseña\n";
// Imprimir menú
System.out.println(menu);
int longitud = 5; // Longitud de la contraseña
// Saber si usuario quiere repetidos
boolean conRepetidos = obtenerConRepetidos();
String passwordCorrecto = obtenerPasswordAleatoria(conRepetidos, longitud);
int intentos = 1;
while (true) {// Ciclo infinito; se rompe cuando el usuario acierta con "break"
String suposicionUsuario = obtenerSuposicionDeUsuario(longitud);
if (suposicionUsuario.equals(passwordCorrecto)) {
System.out.printf("Ganaste en %d intentos\n", intentos);
break;
}
String pistas = obtenerPistas(suposicionUsuario, passwordCorrecto);
System.out.printf("Incorrecto. Pistas:\n%s\n", pistas);
intentos++;
}
}
private static String obtenerSuposicionDeUsuario(int longitud) {
String eleccion = "";
while (eleccion.length() != longitud) {
System.out.println("¿Cuál crees que es la contraseña?: ");
Scanner sc = new Scanner(System.in);
eleccion = sc.nextLine();
}
return eleccion;
}
private static boolean obtenerConRepetidos() {
System.out.println("¿Puede incluir repetidos? 1 = sí. 0 = no ");
return new Scanner(System.in).nextInt() == 1;
}
private static String obtenerPistas(String suposicionPassword, String passwordCorrecto) {
String pistas = "";
for (int x = 0; x < suposicionPassword.length(); x++) {
// Si está en el lugar correcto se indica con un *
if (suposicionPassword.charAt(x) == passwordCorrecto.charAt(x)) {
pistas += "*";
continue;
}
// Si está en la cadena pero no en el lugar correcto, se indica con un _
int indiceCaracter = passwordCorrecto.indexOf(suposicionPassword.charAt(x));
if (indiceCaracter != -1) {
pistas += "_";
continue;
}
// Finalmente, si ninguna de las condiciones de arriba se cumple, el carácter no
// está
pistas += " ";
}
return pistas;
}
private static String obtenerPasswordAleatoria(boolean conRepetidos, int longitud) {
String muestra = "0123456789";
Random random = new Random(System.currentTimeMillis());
String pass = "";
for (int x = 0; x < longitud; x++) {
// Tomamos un dígito aleatorio
int indiceAleatorio = random.nextInt(muestra.length());
char digitoAleatorio = muestra.charAt(indiceAleatorio);
// Si no quieren repetidos...
if (!conRepetidos) {
// Mientras que en la cadena ya exista el carácter que acabamos de generar
while (pass.indexOf(digitoAleatorio) != -1) {
// Generamos otro
indiceAleatorio = random.nextInt(muestra.length());
digitoAleatorio = muestra.charAt(indiceAleatorio);
}
}
// De cualquier forma, agregamos el dígito a la cadena
pass += digitoAleatorio;
}
return pass;
}
}
Si quieres puedes ejecutarlo directamente en este enlace: jugar en línea.
Yo lo he jugado y probado un poco, aquí mis resultados:
Dejo algunos enlaces de interés. Te invito a ver más tutoriales sobre Java o ver el código fuente de videojuegos.
Ya te enseñé cómo convertir una aplicación web de Vue 3 en una PWA. Al…
En este artículo voy a documentar la arquitectura que yo utilizo al trabajar con WebAssembly…
En un artículo anterior te enseñé a crear un PWA. Al final, cualquier aplicación que…
Al usar Comlink para trabajar con los workers usando JavaScript me han aparecido algunos errores…
En este artículo te voy a enseñar cómo usar un "top level await" esperando a…
Ayer estaba editando unos archivos que son servidos con el servidor Apache y al visitarlos…
Esta web usa cookies.