Actividad 6: Los Sudokus Parte 1
Descripción
Eres el encargado de desarrollar un sistema para resolver Sudokus. El sistema debe incluir las siguientes funcionalidades:
Generar Sudoku: Permitir a los usuarios generar un Sudoku aleatorio de 9x9.
Resolver Sudoku: Permitir a los usuarios resolver un Sudoku ingresando los números en las posiciones correspondientes.
Validar Sudoku: Permitir a los usuarios validar si un Sudoku es correcto o no.
Mostrar Sudoku: Permitir a los usuarios mostrar el Sudoku en un formato legible.
Guardar Sudoku: Permitir a los usuarios guardar el Sudoku en un archivo de texto.
Requisitos
El sistema debe ser desarrollado en Java.
Utilizar arreglos bidimensionales para almacenar el Sudoku.
Utilizar JOptionPane para la interacción con el usuario.
El sistema debe ser modular y seguir el principio de responsabilidad única.
El Sudoku debe ser generado de forma aleatoria y debe cumplir con las reglas del Sudoku.
El Sudoku debe ser resuelto utilizando un algoritmo de backtracking.
El Sudoku debe ser validado verificando que no haya números repetidos en filas, columnas y subcuadrantes.
El Sudoku debe ser mostrado en un formato legible utilizando JOptionPane.
Desarrollo de la Actividad
Para este entregable crearemos el paquete com.tec.games.sudoku
, y nos centraremos en crear la clase SudokuGenerator
que se encargará de generar un Sudoku aleatorio usando un algoritmo de backtracking. La clase debe incluir los siguientes métodos:
generateSudoku()
: Genera un Sudoku aleatorio de 9x9.isValid(int row, int col, int num)
: Verifica si es válido colocar un número en una posición específica.isValidRow(int row, int num)
: Verifica si el número ya existe en la fila.isValidColumn(int col, int num)
: Verifica si el número ya existe en la columna.isValidBox(int row, int col, int num)
: Verifica si el número ya existe en el subcuadrante.printSudoku()
: Imprime el Sudoku en un formato legible.
La clase debe de contar con los siguientes atributos:
int[][] sudoku
: Matriz que representa el Sudoku, recuerda que el Sudoku es una matriz de 9x9.
Solución paso a paso
Crear el paquete
com.tec.games.sudoku
: En este paquete, define la claseSudokuGenerator
.Implementar el método
generateSudoku()
: Este método debe generar un Sudoku aleatorio de 9x9 utilizando un algoritmo de backtracking.Implementar el método
fillboard(int row, int col)
: Este método debe llenar el Sudoku de forma recursiva.Si la fila y la columna son mayores a 8, significa que se ha llenado todo el Sudoku y se debe retornar
true
.Si la columna es mayor a 8, se debe incrementar la fila y reiniciar la columna a 0.
Se debe generar un número aleatorio entre 1 y 9 y verificar si es válido colocarlo en la posición (row, col).
Si es válido, se debe colocar el número en la posición (row, col) y continuar con el siguiente número.
Si no es válido, se debe intentar colocar otro número en la misma posición.
Implementar el método
isValid(int row, int col, int num)
: Este método debe verificar si es válido colocar un número en una posición específica del Sudoku.**Implementar los métodos
isValidRow(int row, int num)
,isValidColumn(int col, int num)
yisValidBox(int row, int col, int num)
: Estos métodos deben verificar si el número ya existe en la fila, columna o subcuadrante correspondiente.Implementar el método
isValidColumn(int col, int num)
: Este método debe verificar si el número ya existe en la columna. Para ello se debe recorrer la columna y comparar el número que se quiere colocar con los números que ya existen en la columna. Si el número ya existe, se debe retornarfalse
, de lo contrario se debe retornartrue
.Ten en cuenta que existe la clase
IntStream
que permite recorrer un arreglo de enteros y la funciónnoneMatch
que permite verificar si un número no existe en el arreglo.- IntStream.range(0, sudoku.length).noneMatch(i -> sudoku[i][col] == num);
Implementar el método
isValidRow(int row, int num)
: Este método debe verificar si el número ya existe en la fila. Para ello se debe recorrer la fila y comparar el número que se quiere colocar con los números que ya existen en la fila. Si el número ya existe, se debe retornarfalse
, de lo contrario se debe retornartrue
.Ten en cuenta que existe la clase
IntStream
que permite recorrer un arreglo de enteros y la funciónnoneMatch
que permite verificar si un número no existe en el arreglo.- IntStream.range(0, sudoku.length).noneMatch(i -> sudoku[row][i] == num);
Implementar el método
isValidBox(int row, int col, int num)
: Este método debe verificar si el número ya existe en el subcuadrante. Para ello se debe recorrer el subcuadrante y comparar el número que se quiere colocar con los números que ya existen en el subcuadrante. Si el número ya existe, se debe retornarfalse
, de lo contrario se debe retornartrue
.Recuerda que puedes obtener una submatriz de 3x3 utilizando un bucle anidado que recorra las filas y columnas del subcuadrante, o bien utilizando la función
Arrays.copyOfRange
para copiar la submatriz.- int startRow = (row / 3) * 3; int startCol = (col / 3) * 3; for (int i = startRow; i < startRow + 3; i++) { for (int j = startCol; j < startCol + 3; j++) { if (sudoku[i][j] == num) { return false; } } } return true;
- IntStream.range(0, 3).noneMatch(i -> IntStream.range(0, 3).noneMatch(j -> sudoku[startRow + i][startCol + j] == num));
Recuerda que en cualquier caso debes calcular la posición inicial del subcuadrante utilizando la división entera entre 3, y multiplicar el resultado por 3.
Implementar el método
printSudoku()
: Este método debe imprimir el Sudoku en un formato legible utilizando JOptionPane.Crear una clase
Main
: En esta clase, crea un menú de opciones que permita a los usuarios generar un Sudoku, resolverlo, validarlo y mostrarlo. Utiliza la claseSudokuGenerator
para implementar la funcionalidad del sistema.
Las funciones isValidRow
, isValidColumn
y isValidBox
deben de ser privadas, ya que no se utilizarán fuera de la clase SudokuGenerator
.
isValidRow
La función isValidRow
debe de verificar si el número ya existe en la fila, para ello se debe recorrer la fila y comparar el número que se quiere colocar con los números que ya existen en la fila. Si el número ya existe, se debe retornar false
, de lo contrario se debe retornar true
.
isValidColumn
La función isValidColumn
debe de verificar si el número ya existe en la columna, para ello se debe recorrer la columna y comparar el número que se quiere colocar con los números que ya existen en la columna. Si el número ya existe, se debe retornar false
, de lo contrario se debe retornar true
.
isValidBox
La función isValidBox
debe de verificar si el número ya existe en el subcuadrante, para ello se debe recorrer el subcuadrante y comparar el número que se quiere colocar con los números que ya existen en el subcuadrante. Si el número ya existe, se debe retornar false
, de lo contrario se debe retornar true
.
Para recorrer el subcuadrante se debe de saber en qué subcuadrante se encuentra la posición (row, col), para ello se debe de dividir la fila y la columna entre 3, y multiplicar el resultado por 3. Por ejemplo, si la posición es (4, 5), se debe de dividir 4 entre 3 y 5 entre 3, lo que nos da (1, 1). Luego se debe de multiplicar (1, 1) por 3, lo que nos da (3, 3). Por lo tanto, el subcuadrante es el que empieza en la posición (3, 3) y termina en la posición (5, 5). Para recorrer el subcuadrante se debe de recorrer desde la posición (3, 3) hasta la posición (5, 5).
printSudoku
El método printSudoku
debe de imprimir el Sudoku en un formato legible utilizando JOptionPane. Para ello se debe de recorrer la matriz y concatenar los números en una cadena de texto. Luego se debe de mostrar la cadena de texto en un JOptionPane. Para mostrar el Sudoku en un formato legible, se puede utilizar el siguiente formato:
fillboard
El proceso de llenado del Sudoku se realiza de forma recursiva de la siguiente manera:
Se verifica si la fila es distinta de 9, lo que indica que hemos llenado todo el Sudoku, en cuyo caso se retorna
true
.En caso contrario, tomamos un número aleatorio entre 1 y 9 y verificamos si es válido colocarlo en la posición (row, col).
Si es válido, colocamos el número en la posición (row, col) y llamamos recursivamente a
fillboard
con la siguiente posiciónnextRow = (column == 8) ? row + 1 : row;
nextColumn = (column + 1) % 9;
Si la llamada recursiva retorna
true
, significa que hemos llenado el Sudoku correctamente y retornamostrue
.Si la llamada recursiva retorna
false
, significa que no hemos podido llenar el Sudoku, por lo que debemos eliminar el número colocado en la posición (row, col), por lo que lo igualamos a 0 y continuar con el siguiente número.Si no hemos podido colocar ningún número en la posición (row, col), retornamos
false
.
El proceso previo se ejemplifica en el siguiente código:
Entregables
Código fuente del sistema.
Pruebas funcionales que demuestren el correcto funcionamiento de cada una de las funcionalidades.
Portada con datos de identificación del equipo de trabajo.
Criterios de Evaluación
Criterio | Descripción | Puntuación |
---|---|---|
Portada | Presentación y datos de identificación del equipo de trabajo. | 10% |
Código | Calidad del código, modularidad y uso de buenas prácticas. | 20% |
Pruebas | Cobertura de pruebas funcionales y casos de prueba. | 30% |
Modularidad | Uso de arreglos bidimensionales. | 20% |
Interacción | Uso de JOptionPane para la interacción con el usuario. | 20% |
Total | 100% |
Notas
El sistema debe ser entregado en un archivo comprimido (zip) que contenga el código fuente y las pruebas.
La fecha de entrega es el 16 de mayo de 2025 a las 23:59 horas.