Nuevo error en el script, pero esta vez fue error de implementación. Ahora sí que tengo la certeza de que funciona bien, pero ya no genera sudokus muy difíciles. Intenta generar con la dificultad que se le indica, pero va sacando sólo los números de los casilleros que puede sin perder la solución única, y a veces da toda la vuelta y no puede sacar muchos números. A continuación, las funciones corregidas:
Código PHP:
function borrarCasilleros($sudokuOriginal, $dificultad=NULL)
{
if($dificultad==NULL)
{
srand(ceil(999999999*microtime()));
$dificultad=rand(1, 28);
}
$arrPosiciones=array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81);
$arrOrden=$arrPosiciones;
shuffle2($arrOrden);
$quitados=0;
$sudokuResultante=$sudokuOriginal;
$limite=$dificultad+35;
$i=1;
while($quitados<$limite && $i<81)
{
$sudokuAnt=$sudokuResultante;
$quitadosAnt=$quitados;
$idx=$arrOrden[$i];
$sudokuResultante[$idx]=NULL;
if(!solucionUnica($sudokuResultante, $quitados, $idx))
{
$quitados=$quitadosAnt;
$sudokuResultante=$sudokuAnt;
}
$i++;
}
$dificultad=$quitados-35;
echo "<br />Dificultad: $dificultad<br />";
return $sudokuResultante;
}
function solucionUnica($sudoku, &$quitados, $idx)
{
$original=array(1, 2, 3, 4, 5, 6, 7, 8, 9);
$cols=array(1=>1, 2=>2, 3=>3, 4=>4, 5=>5, 6=>6, 7=>7, 8=>8, 0=>9);
$cuadrado=array(
1=>'A', 2=>'A', 3=>'A', 4=>'B', 5=>'B', 6=>'B', 7=>'C', 8=>'C', 9=>'C',
10=>'A', 11=>'A', 12=>'A', 13=>'B', 14=>'B', 15=>'B', 16=>'C', 17=>'C', 18=>'C',
19=>'A', 20=>'A', 21=>'A', 22=>'B', 23=>'B', 24=>'B', 25=>'C', 26=>'C', 27=>'C',
28=>'D', 29=>'D', 30=>'D', 31=>'E', 32=>'E', 33=>'E', 34=>'F', 35=>'F', 36=>'F',
37=>'D', 38=>'D', 39=>'D', 40=>'E', 41=>'E', 42=>'E', 43=>'F', 44=>'F', 45=>'F',
46=>'D', 47=>'D', 48=>'D', 49=>'E', 50=>'E', 51=>'E', 52=>'F', 53=>'F', 54=>'F',
55=>'G', 56=>'G', 57=>'G', 58=>'H', 59=>'H', 60=>'H', 61=>'I', 62=>'I', 63=>'I',
64=>'G', 65=>'G', 66=>'G', 67=>'H', 68=>'H', 69=>'H', 70=>'I', 71=>'I', 72=>'I',
73=>'G', 74=>'G', 75=>'G', 76=>'H', 77=>'H', 78=>'H', 79=>'I', 80=>'I', 81=>'I');
$cuadrados=array(
'A'=>array(1, 2, 3, 10, 11, 12, 19, 20, 21),
'B'=>array(4, 5, 6, 13, 14, 15, 22, 23, 24),
'C'=>array(7, 8, 9, 16, 17, 18, 25, 26, 27),
'D'=>array(28, 29, 30, 37, 38, 39, 46, 47, 48),
'E'=>array(31, 32, 33, 40, 41, 42, 49, 50, 51),
'F'=>array(34, 35, 36, 43, 44, 45, 52, 53, 54),
'G'=>array(55, 56, 57, 64, 65, 66, 73, 74, 75),
'H'=>array(58, 59, 60, 67, 68, 69, 76, 77, 78),
'I'=>array(61, 62, 63, 70, 71, 72, 79, 80, 81)
);
$idxColumna=$cols[$idx%9];
$idxFila=ceil($idx/9);
$idxCuadrado=$cuadrado[$idx];
$idxsColumna=array();
$idxsFila=array();
for($j=1; $j<=9; $j++)
{
array_push($idxsColumna, ($idxColumna+9*($j-1)));
array_push($idxsFila, ($j+($idxFila-1)*9));
}
$idxsCuadrado=$cuadrados[$idxCuadrado];
$columna=obtenerPorcion($sudoku, $idxsColumna);
$fila=obtenerPorcion($sudoku, $idxsFila);
$cuadro=obtenerPorcion($sudoku, $idxsCuadrado);
$opciones=array_diff($original, $columna, $fila, $cuadro);
if(count($opciones)==0)
{
echo "ERROR.";
}
elseif(count($opciones)==1)
{
$quitados++;
return true;
}
else
{
return false;
}
}
). ¡Suerte!