Sie sind auf Seite 1von 7

Juego Sudoku en Java

Introduccin
Este artculo es sobre la aplicacin de un juego de Sudoku en Java. Esta versin cuenta con
una interfaz intuitiva con la capacidad de utilizar la ayuda y para comprobar si hay
errores. Encendido de ayuda marcar todos los campos posibles para el nmero
seleccionado. Despus de la comprobacin de errores, el programa marca campos vlidos
verde y campos no vlidos rojo. Las reglas utilizadas en esta aplicacin son los siguientes:

o
o
o

Un entero slo puede aparecer una vez en ...


... La misma fila.
... La misma columna.
... La misma regin de 3x3.
Un juego tiene una sola solucin.

Implementacin
Modelo
La parte ms importante de esta aplicacin es en la clase de juegos, que incluye las
siguientes funcionalidades:

Generar una nueva solucin;


Generar un nuevo juego de una solucin;
Lleve un registro de entrada del usuario;
Compruebe la entrada del usuario frente a solucin generada;
Lleve un registro de nmero seleccionado;
Lleve un registro de la ayuda est encendido o apagado.

Porque la clase de juego se extiende observable, que puede y no notificar a


los observadores cuando se han realizado ciertos cambios. Esta aplicacin
particular contiene dos observadores,ButtonPanel y SudokuPanel. Cuando la clase
de juego ejecuta setChanged () seguido denotifyObservers (...), los observadores
ejecutar su mtodo de actualizacin (...).
Adems de la clase de juego, el modelo consiste en una enumeracin
llamada updateAction que le dir qu tipo de observadores actualizacin ha tenido lugar.

Generar solucin
Antes de que podamos comenzar a generar un juego, primero tenemos que generar una
solucin. Esto se logra mediante el mtodo siguiente, que debe ser llamado por el usuario
como generateSudoku (new int [9] [9], 0). Se toman los siguientes pasos:
1. Compruebe si se encuentra una solucin.
o Encontrado -> se devuelve solucin.
o No encontrado -> continuar.
2. X (del campo actual) se encuentra al encontrar el resto de la divisin del ndice actual por el
conde de campos seguidos en la operacin de mdulo.
3. Y (del campo actual) se obtiene dividiendo el ndice actual por el recuento de los campos
en una fila.
4. Un ArrayList se llena con los nmeros del 1 al 9 y barajadas. Arrastrar los pies es
importante porque de lo contrario siempre se obtiene la misma solucin.
5. Mientras hay un nmero en el ArrayList, lo siguiente ser ejecutado:
1. El prximo nmero posible se obtiene mediante el mtodo getNextPossibleNumber
(int [] [], int, int, List <Integer>), que se explicar ms adelante. Si no hay un
siguiente nmero posible (valor de retorno de -1), se devuelve null.
2. Nmero encontrado se coloca en la ubicacin actual.
3. El mtodo se llama de forma recursiva con un aumento del ndice, y el valor de regresar se
almacena en una variable.
4. Si esta variable no es nulo, se devuelve; de lo contrario, la ubicacin actual se vuelve
a poner a 0 (es decir, el campo es un espacio en blanco).
6. se devuelve nulo. Nunca se lleg a esta parte, es de esperar.

Contraer | Copiar Cdigo

private int [] [] generateSolution (int [] [] juego,


int index) {if (ndice>
80) partido de vuelta;
int x = ndice%
9; int y = ndice / 9;
List <Integer> Nmeros = new ArrayList <Integer> ();
for (int i = 1; i <= 9; i ++)
numbers.add (i);
Collections.shuffle (nmeros);
while (numbers.size ()>
0) {int numero = getNextPossibleNumber (juego, x, y, nmeros);
si (nmero == 1) return null;
juego [y] [x] = nmero;
int [] [] = tmpGame generateSolution (juego, index +

1); if (! tmpGame = null) return


tmpGame;
juego [y] [x] = 0;
}
devolver null;
}

Como se ha dicho anteriormente, el mtodo getNextPossibleNumber (int [] [],


int, int, List <Integer>) se utiliza para obtener el siguiente nmero posible. Se
necesita un nmero de la lista y comprueba si es posible en el x dado y la posicin y en el
juego dado. Cuando descubierto que es posible, se devuelve el nmero. Si la lista est vaca
y por lo tanto no hay ningn nmero es posible en este lugar, se devuelve -1.
Contraer | Copiar Cdigo

int getNextPossibleNumber (int [] [] juego, int x, int y, List <Integer> Nmeros)


{while privado (numbers.size ()>
0) {int numero = numbers.remove
(0); si (isPossibleX (juego , y, nmero)
&& IsPossibleY (juego, x, nmero)
&& IsPossibleBlock (juego, x, y, nmero))
nmero regresar;
}
volver - 1;
}

Generar Juego
Generacin de un juego se consigue simplemente mediante la constante eliminacin de un
campo aleatorio y asegurndose de que el juego sigue siendo vlida. Vlido significa que
slo hay una solucin. Esto se consigue mediante los siguientes mtodos. El usuario debe
llamar el primer mtodo, que utiliza el segundo mtodo. Voy a describir los pasos de
nuevo.
1. Una lista est llena de todas las posiciones posibles.
2. La lista es barajada. Yo no s por qu. Sospecho que de esta manera, los espacios se
distribuyen mejor. Con el resultado de que el juego es ms difcil.
3. La lista se pasa al mtodo generateGame (int [] [], List <Integer>) y el valor de
retorno ser devuelto.
Contraer | Copiar Cdigo

private int [] [] generateGame (int [] [] juego) {


List <Integer> posiciones = new ArrayList <Integer> ();
for (int i = 0; i <81; i ++)
posiciones.aadir (i);
Collections.shuffle (posiciones);
volver generateGame (juegos, posiciones);
}

1.
1.
2.
3.
4.

Siempre y cuando no son puestos en la lista, el siguiente ser ejecutado:


Una posicin se toma de la lista y se almacena en una variable.
x e y se calculan a partir de esta posicin.
Valor en esta posicin se almacena en la variable temp.
Valor en este punto se establece en 0 (lo que significa que el campo es un espacio en
blanco).

5. Este paso es fundamental. Como la eliminacin del valor en la posicin significa que el
juego ya no es vlido, el valor en la posicin se vuelve a poner. De lo contrario, el juego
sigue siendo el mismo.
2. Se devuelve el juego.
Contraer | Copiar Cdigo

private int [] [] generateGame (int [] [] juego, List <Integer> posiciones)


{while (positions.size ()>
0) {position int = positions.remove
(0); int x = posicin%
9; int y = posicin /
9; int temp = juego [y] [x];
juego [y] [x] = 0;
if (! isValid (juego))
juego [y] [x] = temp;
}
regresar juego;
}

Como puede ver, este mtodo se utiliza para pasar valores por defecto. Entonces por qu
el nuevo int [] {0}?Esta es la forma ms comn de pasar un nmero entero por
referencia, en lugar de por valor.
Contraer | Copiar Cdigo

isValid private boolean


([] [] juego int) {return isValid (juego, 0, new
}

int [] {0});

Un juego vlido tiene en cada fila, cada columna y cada regin de los nmeros de 1 a 9.
Adems, slo debe haber una solucin existente. Para lograr esto, todos los campos
abiertos se llenan con el primer valor vlido. Incluso despus de encontrar una solucin, la
bsqueda contina poniendo el siguiente valor vlido en un campo abierto.Si se encuentra
una segunda solucin, entonces se detiene la bsqueda y el mtodo
devuelve false. Siempre habr al menos una solucin (de ah juego es una solucin
incompleta), as que si hay menos de dos soluciones, el juego es vlida y el mtodo
retorna verdadero. Paso a paso:
1. Compruebe si se encuentra una solucin.
o Encontrado -> aumento numberOfSolutions y devolver true si es igual a 1; en
caso contrario.
o No encontrado -> continuar.
2. Calcula x e y del ndice.
3. Compruebe si el campo actual es un espacio en blanco (igual a 0).
o Verdadero
1. Llenar una lista con los nmeros 1 a 9.
2. Mientras que la lista contiene nmeros, ejecutar lo siguiente:
1. Obtener el siguiente nmero posible. Si el valor devuelto es igual a -1, realizar un descanso
que resulta un retorno de la verdadera.
2. Definir este nmero en el campo actual.
3. Llame a este mtodo de forma recursiva y al instante comprobar sobre el valor devuelto.
Verdadero -> una o ninguna solucin encontrada, continuar la bsqueda.

Falso -> ms de una solucin encontrada, dejar de buscar. Restaurar juego y volver falsa.
4. Restaurar valor del campo actual en 0 (lo que significa que est en blanco).
o Falso
1. Llame a este mtodo de forma recursiva y al instante comprobar sobre el valor devuelto.
Verdadero -> seguir (lo que resulta en la devolucin de verdad).
Falso -> return false.
4. Devuelve verdadero.

Contraer | Copiar Cdigo

isValid private boolean (int [] [] juego, int index, int [] numberOfSolutions)


{if (ndice>
80) de retorno ++ numberOfSolutions [0] == 1;
int x = ndice%
9; int y = ndice / 9;
si (juego [y] [x] == 0) {
List <Integer> Nmeros = new ArrayList <Integer> ();
for (int i = 1; i <= 9; i ++)
numbers.add (i);
while (numbers.size ()>
0) {int = nmero getNextPossibleNumber (juego, x, y,
nmeros), si (nmero == 1) romper;
juego [y] [x] = nmero;
if (! isValid
juego [y]
0; return
}
juego [y] [x]

(juego, index + 1, numberOfSolutions)) {


[x] =
false;

= 0;
}
} Else if (! IsValid (juego, ndice +
1, numberOfSolutions)) return false;
return true;
}

Compruebe Juego
Con control de entrada del usuario, comparamos cada campo en el partido contra el campo
correspondiente en la solucin. El resultado se almacena en una matriz booleana de dos
dimensiones. El nmero seleccionado tambin se establece en 0 (es decir, se selecciona
ningn nmero). Todos los observadores se les notifica que el modelo ha cambiado con
la updateAction correspondiente.
Contraer | Copiar Cdigo

pblica checkGame void () {


selectedNumber =
0; for (int y = 0; y
<9; y ++) {for (int x = 0; x <9; x ++)
comprobar [y] [x] = juego [y] [x] == solucin [y] [x];
}
setChanged ();
notifyObservers (UpdateAction.CHECK);
}

Ver y Controlador
No hay mucho que decir sobre la parte de la vista, slo la estructura de los paneles. Los
controladores reaccionan a la entrada del usuario e implementar cambios en el modelo. El
modelo notifica que se ha cambiado. Las respuestas de vista a esta notificacin y
actualizaciones. Estas actualizaciones de la vista se limitan a cambiar los colores y cambiar
el nmero de un campo. No hay ciencia del cohete en cuestin.

Sudoku
La vista tambin es el punto de entrada de la presente solicitud; la clase Sudoku contiene el
mtodo principal. Esta clase se acumula la interfaz de usuario mediante la creacin de
un JFrame y colocando SudokuPanel yButtonPanel dentro de este marco. Tambin crea
la clase de juego, y aade SudokuPanel y ButtonPanelcomo observadores a la
misma.

SudokuPanel y campos
SudokuPanel contiene 9 paneles sub conteniendo cada uno 9 campos. Todos los paneles
de sub y campos se colocan en un GridLayout de 3x3. Cada panel secundario representa
una regin de un juego de Sudoku, y se utiliza principalmente para la elaboracin de una
frontera que separa visualmente cada regin. Tambin reciben
elSudokuController aadido a ellos, que es el encargado de la entrada del usuario de
procesamiento por el ratn.

ButtonPanel
ButtonPanel contiene dos paneles con un borde con ttulo. El primer panel contiene tres
botones. Nuevo botn para iniciar un nuevo juego, el botn Comprobar para comprobar la
entrada del usuario, y el botn Salir para salir de la aplicacin. El segundo panel contiene 9
botones de alternar colocados dentro de un grupo de botones. De esta manera, ellos
reaccionan como botones de radio. Al hacer clic en uno de estos botones de seleccin fijar
el nmero seleccionado correspondiente en la clase de juegos.

Puntos de inters

Para pasar un nmero entero por referencia en lugar de por valor, utilice una matriz de
enteros.
Contraer | Copiar Cdigo

isValid (juego, 0, new int []


{0}); isValid private boolean (int [] [] juego, int index, int [] numberOfSolutions);

Encontrar los valores de y de una regin de base xy, utilice el siguiente:


Contraer | Copiar Cdigo

= int x1 x <3 0: x <6 3:


6; int y1 = y <3 0:?? y <6 3:?? 6;

Historia

Versin inicial.

Disculpas
Uno, si he conducido Ests loco con mi mala Ingls, me disculpo. Dos, si he conducido Ests
loco antes, porque por lo general mi fuente no contiene comentarios, me disculpo, y te
puedo decir, en este caso, lo hace. No porque reconozco su utilidad, pero para evitar
discusiones. Tres, si no he mencionado antes de que pueda utilizar el botn derecho del
ratn para borrar un campo, me disculpo.

Das könnte Ihnen auch gefallen