lunes, 31 de diciembre de 2007

Sudoku en java

Este es un programa hecho en java para resolver sudokus, por medio de fuerza bruta.
Lo que hace es tomara a cada cuadrito (lugar donde va el número) como un TDA árbol con nueve hijos (1,2,3,4,5,6,7,8,9), por lo tanto tendremos 81 árboles con sus respectivos hijos.
Lo que prosigue es recorrer la fila, la columna y la matriz del cudrito quitando los números ya existenetes en la fila, columna y en la matriz, reduciendo los hijos del cuadrito. Llegaremos a un punto donde el cuadrito tendra un solo hijo, este se imprime y se vuelve a recorrer todo el algoritnmo (fuerza bruta). Cabe mencionar que el algoritmo no resuelve todos los sudokus. Veamos el código:

private boolean Resuelve() {//metodo que resuelve
String txtAlmacen="", txtLinea="";
boolean seAgrega=false;
int cont=1;
for (int i=0;i<9;i++)//recorre toda la matriz =81
for (int j=0;j<9;j++) {
raiz=new Nodo();//genera 81 variables
raiz.cuadro = arreglo[i][j];
if (raiz.cuadro == 0) {
raiz.posible = QuitaHijos(raiz,i,j);//quita hijos
for (int k=0;k<9;k++) {
if (raiz.posible[k] !=0) {//es un posible
txtLinea+=raiz.posible[k]+" ";
}
}
//si solo hay un numero en el arreglo lo guardamos directo en el arreglo
if (txtLinea.length()==2) {
seAgrega=true;
raiz.cuadro=Integer.parseInt(txtLinea.substring(0,1));//recordar # y espacio
txtLinea+="\n Asignado el valor al tablero";
jTable1.setValueAt(raiz.cuadro,i,j);
arreglo[i][j] = raiz.cuadro;
}
txtAlmacen+="Cuadro "+(cont++)+": "+txtLinea+"\n";
txtLinea="";
}
else txtAlmacen+="Cuadro "+(cont++)+": "+raiz.cuadro+" YA FIJO\n";
txtHijos.setText(txtAlmacen);
}
if(seAgrega) return true;
else return false;
}
El método resuelve basicamente checa los posibles números que van en el cuadrito.

Ahora checamos el método quita hijos:


public int[] QuitaHijos (Nodo cuadro, int fila, int columna) {
for (int h=0; h<9;h++) {
if (arreglo[fila][h] != 0) {//hay numero ¿cual?
int num = arreglo[fila][h];
cuadro.posible[num-1]=0;
}

if (arreglo[h][columna] != 0) {//hay numero ¿cual?
int num = arreglo[h][columna];
cuadro.posible[num-1]=0;
}
}
int iniFila=0, iniColum=0, finFila=0, finColum=0;//Checamos en que sub-matriz estamos
//sirve para el ciclo for posteriro
if (fila<3 && columna<3) {iniFila=0; iniColum=0; finFila=3; finColum=3;}
if (fila<3 && columna>2 && columna<6) {iniFila=0; iniColum=3; finFila=3; finColum=6;}
if (fila<3 && columna>5 && columna<9) {iniFila=0; iniColum=6; finFila=3; finColum=9;}
if (fila>2 && fila<6 && columna<3) {iniFila=3; iniColum=0; finFila=6; finColum=3;}
if (fila>2 && fila<6 && columna>2 && columna<6) {iniFila=3; iniColum=3; finFila=6; finColum=6;}
if (fila>2 && fila<6 && columna>5 && columna<9) {iniFila=3; iniColum=6; finFila=6; finColum=9;}
if (fila>5 && columna<3) {iniFila=6; iniColum=0; finFila=9; finColum=3;}
if (fila>5 && columna>2 && columna<6) {iniFila=6; iniColum=3; finFila=9; finColum=6;}
if (fila>5 && columna>5 && columna<9) {iniFila=6; iniColum=6; finFila=9; finColum=9;}
for(int i=iniFila;i < finFila;i++)
for(int j=iniColum;j < finColum;j++) {
int num= arreglo[i][j];
if(num!=0)
cuadro.posible[num-1]=0;
}
return cuadro.posible;
}


Estos son los dos método escenciales para la solución, el resto depende de ustedes

No hay comentarios: