Tema: Sudoku
Ver Mensaje Individual
  #4 (permalink)  
Antiguo 22/08/2005, 19:57
Avatar de derkenuke
derkenuke
Colaborador
 
Fecha de Ingreso: octubre-2003
Ubicación: self.location.href
Mensajes: 2.665
Antigüedad: 20 años, 6 meses
Puntos: 45
Mmm, veo cuasi-imposible arreglar esos "-1", y mucho menos evitarlos. Asi que como he visto que tras varios intentos el sodoku sale perfecto (tras muuchos intentos, a veces puede que 20 o más), pues he decidido hacer un bucle iterativo: hasta que el Sodoku no salga perfecto, que lo vuelva a intentar.

El codigo completo es el siguiente:

Código PHP:
<html>

<
head>
<
title>SODOKU (version final)</title>

<
style>
.
fila_celdas {
    
height:20px;
    
clear:both;
}
.
fila_cuadrantes {
    
height:62px;
    
clear:both;
    
text-align:center;
}
.
celda {
    
bordersolid 1px black;
    
text-align:center;
    
width20pxheight:20px;
    
font-size:10px;
    
font-family:tahoma;
    
float:left;
    
margin:0px;
}
.
caja {
    
width75pxheight:75px;
    
float:left;
    
text-align:center;
    
margin:0px;
}
</
style>

</
head>
<
body>

<
script>


var 
X=9;    // celdas de lado


//INICIALIZACION DEL ARRAY SODOKU (Array de 4 dimensiones)
var sodoku=new Array();        //contiene todas las cajas (X cajas)
for(var x=0;x<X/3;x++) {        //cajaX
    
sodoku[x]=new Array(X/3);
    for(var 
y=0;y<X/3;y++) {    //cajaY
        
sodoku[x][y]=new Array(X/3);
        for(var 
i=0n=0;i<3;i++) {        //celdaX
            
sodoku[x][y][i]=new Array(3);
            for(var 
j=0;j<3;j++) {    //celdaY
                
sodoku[x][y][i][j]=new Array(3);
            }
        }
    }
}
// asi el array queda sodoku[cajaX][cajaY][celdaX][celdaY]



//funcion document.write, no tan engorrosa y con opcion de salto <br />
function e(q,salto) { document.write(q); if(saltodocument.write("<br />"); }



// imprimimos la estructura HTML de divs para luego solo tener que poner los valores
e('<div id="estado"><h2>Generando...</h2> Espere unos instantes...<br><br></div>');
for(var 
x=0x<X/3x++) {        //cajaX
    
e('<div class="fila_cuadrantes">');
    for(var 
y=0y<X/3y++) {    //cajaY
        
e('<div class="caja" id="caja_'+x+'_'+y+'">');
        for(var 
i=0;i<3;i++) {        //celdaX
            
e('<div class="fila_cajas">');
            for(var 
j=0;j<3;j++) {    //celdaY
                
e('<div class="celda" id="sodoku_'+x+'_'+y+'_'+i+'_'+j+'"></div>');
            }
            
e('</div>');
        }
        
e('</div>');
    }
    
e('</div>');
}
e("&nbsp;",1);


//actualiza los valores del array sodoku en la estructura de divs
function imprime_sodoku() {
    for(var 
x=0;x<X/3;x++)         //cajaX
        
for(var y=0;y<X/3;y++)     //cajaY
                
for(var i=0;i<3;i++)        //celdaX
                    
for(var j=0;j<3;j++)    //celdaY
                        
if( (c=sodoku[x][y][i][j])==-1)
                            
document.getElementById("sodoku_"+x+"_"+y+"_"+i+"_"+j).innerHTML="-";
                        else
                            
document.getElementById("sodoku_"+x+"_"+y+"_"+i+"_"+j).innerHTML=c;
}

/**************************************************************************/
// FUNCIONES GET_____

//nos devuelve un array con todos los elementos de una fila respecto a una celda
function getFila(x,y,i,j) {
    var 
dev=new Array();
    for(
_y=0_y<X/3_y++)        //fila de cajas
        
for(_j=0_j<X/3_j++)
            
dev.splice(dev.length0sodoku[x][_y][i][_j]);    //cogemos la fila entera de celdas
    
return dev;
}

//nos devuelve un array con todos los elementos de una columna respecto a una celda
function getColumna(x,y,i,j) {
    var 
dev=new Array();
    for(
_x=0_x<X/3_x++)        //columna de cajas
        
for(_i=0_i<3_i++)        // cada celda en la columna _j
            
dev.splice(dev.length0sodoku[_x][y][_i][j]);
    return 
dev;
}

//nos devuelve un solo array con la caja de la celda dada (solo tiene una dimension)
function getCaja(x,y) {
    var 
dev=new Array();
    for(
_i=0_i<3_i++)
        for(
_j=0_j<X/3_j++)
            
dev.splice(dev.length0sodoku[x][y][_i][_j]);
    return 
dev;
}

/**************************************************************************/
// RELLENAR EL SODOKU


var nums_posibles=new Array(X);
for(var 
a=0;a<X;a++) nums_posibles[a]=a;

//busca un numero dentro de un array de numero
// y devuelve su indice. Si no lo encuentra devuelve -1
function numAt(arr,num) {
    for(var 
a=0a<arr.lengtha++)
        if(
arr[a]==num)
            return 
a;
    return -
1;
}

//elimina del array 'total' todos los numeros del array 'posibilidades', y devuelve el nuevo 'total'
// si posibilidades es un numero, no un array, tambien puede hacerlo
function eliminaPosibilidades(totalposibilidades) {
    if(
typeof posibilidades=="number") {
        var 
esta=numAt(total,posibilidades);
        if(
esta!=-1)
            
total.splice(esta,1);
    }
    else {
        for(var 
a=0a<posibilidades.lengtha++) {
            var 
esta=numAt(total,posibilidades[a]);
            if(
esta!=-1)
                
total.splice(esta,1);
        }
    }
    return 
total;
}

//copia un array y lo devuelve
function copia(arr) {
    var 
dev=new Array();
    for(var 
a=0;a<arr.lengtha++)
        
dev[dev.length]=arr[a];
    return 
dev;
}



function 
relleno() {

    var 
hayMenosUno=false;
    
    
//rellenamos de "-1":
    
for(var x=0;x<X/3;x++)         //cajaX
        
for(var y=0;y<X/3;y++)  //cajaY
                
for(var i=0;i<3;i++)        //celdaX
                    
for(var j=0;j<3;j++)    //celdaY
                        
sodoku[x][y][i][j]= -1;
    
    
//rellenamos celda a celda
    
for(var x=0;x<X/&& !hayMenosUno;x++)         //cajaX
        
for(var y=0;y<X/&& !hayMenosUno;y++)  //cajaY
                
for(var i=0;i<&& !hayMenosUno;i++)        //celdaX
                    
for(var j=0;j<&& !hayMenosUno;j++) {    //celdaY
                        
                        
var nums=copia(nums_posibles);
                        
nums=eliminaPosibilidades(numsgetFila(x,y,i,j) );
                        
nums=eliminaPosibilidades(numsgetColumna(x,y,i,j) );
                        
nums=eliminaPosibilidades(numsgetCaja(x,y) );
                        if(
nums.length!=0)    //nos hemos quedado sin numeros para poder poner
                            
sodoku[x][y][i][j]=numsparseInt(Math.random()*nums.length) ];
                        else
                            
hayMenosUno=true;
                        
                    }
                    
    
imprime_sodoku();
        
    if(
hayMenosUno) {
        
document.getElementById("estado").innerHTML="<h2>Generando...</h2> Espere unos instantes...<br><br>";
        
setTimeout("relleno()"50);
    }
    else {
        
document.getElementById("estado").innerHTML="<h2>Su sodoku</h2>Su Sodoku esta listo.";
    }
    
}
relleno();


</script>


</body>

</html> 
Se irá generando (lo he agilizado mucho creo, en cuanto detecta el error ya no sigue) hasta conseguir el perfecto.

Mi idea es una vez este generado el sodoku, dar la opcion de jugar a esa tabla en una nueva ventana. Se pasaria el juego entero mediante un formulario (metodo POST, supongo) a una ventana nueva.

El caso es que no tengo ni idea de cuántas celdas tengo que ocultar ni mostrar para que sea posible su resolución


Un saludete!
__________________
- Haz preguntas inteligentes, y obtendrás más y mejores respuestas.
- Antes de postearlo Inténtalo y Búscalo.
- Escribe correctamente tus mensajes.