Hola a todos, hoy os voy a explicar como podemos generar un cartón de bingo con Java.
Seguro que alguna vez has jugado al bingo en tu vida, tenemos unos cartones con una serie de números y de huecos, pero ¿Cómo podríamos generarlos? Vamos a verlo.
Formato y reglas de un cartón de bingo
El cartón de bingo tiene unas reglas especificas que se deben cumplir:
- Cada fila tiene 5 números y 4 huecos vacíos.
- Cada columna tiene 1 número y 2 huecos o 2 números y 1 hueco vacío.
- Las columnas están ordenadas de menor a mayor, siendo el menor el que mas arriba este.
- Cada columna tiene un rango de números:
- Columna 1: 1-9
- Columna 2: 10-19
- Columna 3: 20-29
- Columna 4: 30-39
- Columna 5: 40-49
- Columna 6: 50-59
- Columna 7: 60-69
- Columna 8: 70-79
- Columna 9: 80-90
Analiza esta foto y comprueba que se cumple todo lo anterior:
Te dejo un PDF con más ejemplos.
Pasos a realizar para crear un cartón de bingo
¿Cómo lo representamos? El cartón de bingo lo vamos a representar como una matriz de números de 3 filas y 9 columnas. Los huecos los representaremos como un -1.
Tenemos una serie de pasos que tenemos que realizar para generarlo:
- Rellenar nuestra matriz de números.
- Ordenar números por cada columna.
- Poner los huecos.
- Mostrar el cartón, sustituyendo -1 por el carácter deseado.
Seguramente, te estés preguntado que porque no marco los huecos antes de rellenar todo si luego lo voy a sustituir por -1, la razón es simple, por la ordenación de columnas, ya que puede afectar a la ordenación, se puede hacer, pero implica más código.
Código base para nuestro cartón de bingo
Para cada paso, utilizaremos una función pero tendremos un código inicial que es este:
package ejercicio_matrices_ddr_14; import java.util.Arrays; public class Ejercicio_matrices_DDR_14 { public static void main(String[] args) { int[][] carton = new int[3][9]; // Rellenar numeros en el carton // Ordena cada columna del carton // Marca los huecos del cartón // Mostramos el cartón } public static int generaNumeroAleatorio(int minimo, int maximo) { return (int) (Math.random() * (maximo - minimo + 1) + (minimo)); } }
Si te interesa saber más como generar números aleatorios lo puedes ver en este tutorial:
Como generar números aleatorios con el método Math.random de Java
Rellenar números de nuestro cartón de bingo
Nuestro primer paso, será rellenar la matriz de números aleatorios, este seria el código para rellenar los números:
public static void rellenarNumerosCarton(int[][] carton) { // Declaramos las variables necesarias int numAleatorio; boolean repetido; // Recorre los números for (int j = 0; j < carton[0].length; j++) { for (int i = 0; i < carton.length; i++) { do { repetido = false; // Genera un número aleatorio // En la columna 0, el numero estará entre 1 y 9 // Entre las columnas 1 y 7, el numero estará entre (10 * j) y ((10 * j) + 9) // En la columna 8, el numero estará entre 80 y 90 switch (j) { case 0: numAleatorio = generaNumeroAleatorio(1, 9); break; case 8: numAleatorio = generaNumeroAleatorio(80, 90); break; default: numAleatorio = generaNumeroAleatorio(10 * j, (10 * j) + 9); break; } // Se puede hacer con un bucle // Comprobamos si se repite el primero if (i == 1 && carton[0][j] == numAleatorio) { repetido = true; // Comprobamos si se repite el primero o el segungo } else if (i == 2 && (carton[0][j] == numAleatorio || carton[1][j] == numAleatorio)) { repetido = true; } } while (repetido); // Añadimos el número carton[i][j] = numAleatorio; } } }
Ordenar números por cada columna de nuestro cartón de bingo
El siguiente paso es ordenar cada una de las columnas. Este es el código:
public static void ordenarColumnasCarton(int[][] carton) { int[] numeros = new int[3]; for (int j = 0; j < carton[0].length; j++) { // Obtengo los numeros de la columna x for (int i = 0; i < carton.length; i++) { numeros[i] = carton[i][j]; } // Ordeno los numeros Arrays.sort(numeros); // Vuelvo a asignar los valores, ya ordenados for (int i = 0; i < numeros.length; i++) { carton[i][j] = numeros[i]; } } }
Poner los huecos en nuestro cartón
Esta parte es la más difícil de todas, ya que hay ciertas cosas que debemos tener en cuenta.
Lo primero que podemos pensar, es que si ponemos aleatoriamente los huecos en cada fila ya estaría, el problema de esto es que es muy probable es que se queden columnas sin huecos o que se repartan mal los huecos.
Mi consejo es generar grupos de huecos por cada columna, habiendo 6 grupos de 1 hueco vacío y 3 grupos de 2 huecos vacíos, revisa la foto del inicio y veras que se cumple. Por lo que cuando estemos en una columna que tenga dos huecos, recorreremos de nuevo la columna.
La estrategia es la siguiente, debemos «nivelar» el numero de huecos, es decir, si tenemos 3 huecos en la fila 0 y 1 y en la fila 2 hay 2 huecos, debemos darle prioridad a este ultimo, para que estén nivelados. En caso de empate, elegiremos un hueco al azar. Tendremos un array para indicar si una posición de la columna esta o no disponible para poner un hueco vacio.
Resumen
- Generar un array con 6 unos y 3 doses.
- Recorrer las columnas.
- Marcar todos los huecos disponibles.
- Comprobar si el numero de huecos vacíos son iguales.
- Sino son iguales, buscamos la fila con menores huecos e indicamos que el resto no están disponibles.
- Coloco el hueco vacío en una posición aleatoria disponible.
- Si es una columna en la que tengo que poner 2 huecos vacíos, compruebo el numero de posiciones ocupadas y si es menor que 2, restamos en uno el índice de la columna para que vuelva a hacer todo el proceso.
- Volvemos al paso 3.
Te muestro el código explicado paso a paso:
public static void marcarHuecosCarton(int[][] carton) { // generar un array de 9 posiciones con 6 unos y 3 doses int[] distribucion = {1, 1, 1, 1, 1, 1, 1, 1, 1}; int posicionAleatoria; // Solo generamos 3 doses for (int i = 0; i < 3; i++) { do { posicionAleatoria = generaNumeroAleatorio(0, distribucion.length - 1); } while (distribucion[posicionAleatoria] == 2); // Colocamos un 2 distribucion[posicionAleatoria] = 2; } // Recorrer array e ir llevando una cuenta del numero de huecos de cada fila, no puede superar 4 int numHuecos[] = new int[3]; boolean huecoDisponible[] = new boolean[3]; int menor, filaAleatoria, posOcupadas; boolean iguales; for (int j = 0; j < carton[0].length; j++) { // Marco las posiciones como disponible Arrays.fill(huecoDisponible, true); // Compruebo si son iguales iguales = true; for (int i = 0; i < numHuecos.length - 1 && iguales; i++) { if (numHuecos[i] != numHuecos[i + 1]) { iguales = false; } } // Sino son iguales, debo descartar aquellos que distintos al menor hueco if (!iguales) { // Busco el menor hueco menor = numHuecos[0]; for (int i = 1; i < numHuecos.length; i++) { if (numHuecos[i] < menor) { menor = numHuecos[i]; } } // Marco como no disponible los huecos diferentes al menor for (int i = 0; i < huecoDisponible.length; i++) { if (numHuecos[i] != menor) { huecoDisponible[i] = false; } } } // Compruebo donde colocar los huecos do { // Genero una fila aleatoria filaAleatoria = generaNumeroAleatorio(0, carton.length - 1); // Salgo si el hueco esta disponible y no esta repetido } while (!huecoDisponible[filaAleatoria] || carton[filaAleatoria][j] == -1); // Coloco el hueco carton[filaAleatoria][j] = -1; // Incremento en 1 el numero de huecos de esa fila numHuecos[filaAleatoria]++; // Solo compruebo las posiciones ocupadas si tengo que poner dos huecos if (distribucion[j] == 2) { // Compruebo cuantos huecos hay en la columna posOcupadas = 0; for (int i = 0; i < carton.length; i++) { if (carton[i][j] == -1) { posOcupadas++; } } // Si hay menos posiciones ocupadas que el de la distribucion de la columna, repetimos if (posOcupadas < distribucion[j]) { j--; } } } }
Mostrar el cartón
Y ya por fin, el último paso que es mostrar nuestro cartón. Recuerda que los huecos los hemos marcado como -1, este es el código:
public static void mostrarCarton(int[][] carton) { // Recorremos el carton for (int i = 0; i < carton.length; i++) { for (int j = 0; j < carton[i].length; j++) { // Si es -1, ponemos un * o **, segun la columna if (carton[i][j] == -1) { // Si es la primera columna, pongo un * y sino pongo 2 * if (j == 0) { System.out.print("* "); } else { System.out.print("** "); } } else { // Muestro el valor tal cual System.out.print(carton[i][j] + " "); } } // Salto de linea System.out.println(""); } }
Resultado
El código final es el siguiente:
package ejercicio_matrices_ddr_14; import java.util.Arrays; public class Ejercicio_matrices_DDR_14 { public static void main(String[] args) { int[][] carton = new int[3][9]; // Rellenar numeros en el carton rellenarNumerosCarton(carton); // Ordena cada columna del carton ordenarColumnasCarton(carton); // Marca los huecos del cartón marcarHuecosCarton(carton); // Mostramos el cartón mostrarCarton(carton); } public static void rellenarNumerosCarton(int[][] carton) { // Declaramos las variables necesarias int numAleatorio; boolean repetido; // Recorre los números for (int j = 0; j < carton[0].length; j++) { for (int i = 0; i < carton.length; i++) { do { repetido = false; // Genera un número aleatorio // En la columna 0, el numero estará entre 1 y 9 // Entre las columnas 1 y 7, el numero estará entre (10 * j) y ((10 * j) + 9) // En la columna 8, el numero estará entre 80 y 90 switch (j) { case 0: numAleatorio = generaNumeroAleatorio(1, 9); break; case 8: numAleatorio = generaNumeroAleatorio(80, 90); break; default: numAleatorio = generaNumeroAleatorio(10 * j, (10 * j) + 9); break; } // Se puede hacer con un bucle // Comprobamos si se repite el primero if (i == 1 && carton[0][j] == numAleatorio) { repetido = true; // Comprobamos si se repite el primero o el segungo } else if (i == 2 && (carton[0][j] == numAleatorio || carton[1][j] == numAleatorio)) { repetido = true; } } while (repetido); // Añadimos el número carton[i][j] = numAleatorio; } } } public static void ordenarColumnasCarton(int[][] carton) { int[] numeros = new int[3]; for (int j = 0; j < carton[0].length; j++) { // Obtengo los numeros de la columna x for (int i = 0; i < carton.length; i++) { numeros[i] = carton[i][j]; } // Ordeno los numeros Arrays.sort(numeros); // Vuelvo a asignar los valores, ya ordenados for (int i = 0; i < numeros.length; i++) { carton[i][j] = numeros[i]; } } } public static void marcarHuecosCarton(int[][] carton) { // generar un array de 9 posiciones con 6 unos y 3 doses int[] distribucion = {1, 1, 1, 1, 1, 1, 1, 1, 1}; int posicionAleatoria; // Solo generamos 3 doses for (int i = 0; i < 3; i++) { do { posicionAleatoria = generaNumeroAleatorio(0, distribucion.length - 1); } while (distribucion[posicionAleatoria] == 2); // Colocamos un 2 distribucion[posicionAleatoria] = 2; } // Recorrer array e ir llevando una cuenta del numero de huecos de cada fila, no puede superar 4 int numHuecos[] = new int[3]; boolean huecoDisponible[] = new boolean[3]; int menor, filaAleatoria, posOcupadas; boolean iguales; for (int j = 0; j < carton[0].length; j++) { // Marco las posiciones como disponible Arrays.fill(huecoDisponible, true); // Compruebo si son iguales iguales = true; for (int i = 0; i < numHuecos.length - 1 && iguales; i++) { if (numHuecos[i] != numHuecos[i + 1]) { iguales = false; } } // Sino son iguales, debo descartar aquellos que distintos al menor hueco if (!iguales) { // Busco el menor hueco menor = numHuecos[0]; for (int i = 1; i < numHuecos.length; i++) { if (numHuecos[i] < menor) { menor = numHuecos[i]; } } // Marco como no disponible los huecos diferentes al menor for (int i = 0; i < huecoDisponible.length; i++) { if (numHuecos[i] != menor) { huecoDisponible[i] = false; } } } // Compruebo donde colocar los huecos do { // Genero una fila aleatoria filaAleatoria = generaNumeroAleatorio(0, carton.length - 1); // Salgo si el hueco esta disponible y no esta repetido } while (!huecoDisponible[filaAleatoria] || carton[filaAleatoria][j] == -1); // Coloco el hueco carton[filaAleatoria][j] = -1; // Incremento en 1 el numero de huecos de esa fila numHuecos[filaAleatoria]++; // Solo compruebo las posiciones ocupadas si tengo que poner dos huecos if (distribucion[j] == 2) { // Compruebo cuantos huecos hay en la columna posOcupadas = 0; for (int i = 0; i < carton.length; i++) { if (carton[i][j] == -1) { posOcupadas++; } } // Si hay menos posiciones ocupadas que el de la distribucion de la columna, repetimos if (posOcupadas < distribucion[j]) { j--; } } } } public static void mostrarCarton(int[][] carton) { // Recorremos el carton for (int i = 0; i < carton.length; i++) { for (int j = 0; j < carton[i].length; j++) { // Si es -1, ponemos un * o **, segun la columna if (carton[i][j] == -1) { // Si es la primera columna, pongo un * y sino pongo 2 * if (j == 0) { System.out.print("* "); } else { System.out.print("** "); } } else { // Muestro el valor tal cual System.out.print(carton[i][j] + " "); } } // Salto de linea System.out.println(""); } } public static int generaNumeroAleatorio(int minimo, int maximo) { return (int) (Math.random() * (maximo - minimo + 1) + (minimo)); } }
Veamos algunos ejemplos:
Espero que os sea de ayuda. Si tenéis dudas, preguntad. Estamos para ayudarte.
Deja una respuesta