java

Mastermind en Java – Programación de juego

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:

  • En caso de que el dígito esté en donde debería estar, se coloca un * como pista
  • En caso de que el dígito sea parte de la contraseña, pero no esté en la posición correcta, se va a indicar con un _
  • Finalmente, si el dígito no forma parte de la contraseña entonces se indica con un espacio en blanco

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.

Generación de contraseña aleatoria

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.

Preguntar al usuario preferencias para Mastermind en Java

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.

Generación de pistas para el usuario

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.

Comenzar juego

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,

Mastermind en Java – Juego completo

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:

Mastermind en Java – Ejecución del juego por consola

Conclusión

Dejo algunos enlaces de interés. Te invito a ver más tutoriales sobre Java o ver el código fuente de videojuegos.

Estoy aquí para ayudarte 🤝💻


Estoy aquí para ayudarte en todo lo que necesites. Si requieres alguna modificación en lo presentado en este post, deseas asistencia con tu tarea, proyecto o precisas desarrollar un software a medida, no dudes en contactarme. Estoy comprometido a brindarte el apoyo necesario para que logres tus objetivos. Mi correo es parzibyte(arroba)gmail.com, estoy como@parzibyte en Telegram o en mi página de contacto

No te pierdas ninguno de mis posts 🚀🔔

Suscríbete a mi canal de Telegram para recibir una notificación cuando escriba un nuevo tutorial de programación.
parzibyte

Programador freelancer listo para trabajar contigo. Aplicaciones web, móviles y de escritorio. PHP, Java, Go, Python, JavaScript, Kotlin y más :) https://parzibyte.me/blog/software-creado-por-parzibyte/

Entradas recientes

Servidor HTTP en Android con Flutter

El día de hoy te mostraré cómo crear un servidor HTTP (servidor web) en Android…

4 días hace

Imprimir automáticamente todos los PDF de una carpeta

En este post te voy a enseñar a designar una carpeta para imprimir todos los…

4 días hace

Guía para imprimir en plugin versión 1 desde Android

En este artículo te voy a enseñar la guía para imprimir en una impresora térmica…

1 semana hace

Añadir tasa de cambio en sistema de información

Hoy te voy a mostrar un ejemplo de programación para agregar un módulo de tasa…

2 semanas hace

Comprobar validez de licencia de plugin ESC POS

Los usuarios del plugin para impresoras térmicas pueden contratar licencias, y en ocasiones me han…

2 semanas hace

Imprimir euro € en impresora térmica

Hoy voy a enseñarte cómo imprimir el € en una impresora térmica. Vamos a ver…

4 semanas hace

Esta web usa cookies.