También es preciso saber que si las pistas son menos del 20% de los valores, tiene múltiples soluciones.
Entonces:
- Si un sudoku, tiene una sola solución; la validación la harás con tu matriz del sudoku (resuelta). Comprobando en un bucle que el array Sudoku() (tu le llamas Matriz() ), coincide uno a uno con el array User(). El array User() inicialmente es copia del array Pistas() (por si decide restablecer, se copia de nuevo Pistas() en User()...)
- En cambio si tienes múltiples soluciones, la validación sería recurrir a 1 bucle donde reclamas los ausentes de cada fila, bloque y columna, será validado siempre que en todos los casos dé 0 ausentes.
Código:
Buleano = Funcion ValidarSudokuDeMultiplesSoluciones
buleano ausentes
Bucle para k desde 0 a 8
ausentes = Ausencia (Presencia( GetFila(k) ))
Si ausentes = false Devolver False //y salir de la función
ausentes = Ausencia (Presencia( GetColumna(k) ))
Si ausentes = false Devolver False //y salir de la función
ausentes = Ausencia (Presencia( GetBloque(k) ))
Si ausentes = false Devolver False //y salir de la función
Fin bucle
Devolver True // aparecen todos, una sola vez en fila, columna y bloque.
Fin funcion
NOTA que:
Citar
ausentes = Ausencia (Presencia( Getxxxx(k)))
es una llamada a otra función con la salida de la interna...Es decir, primero se llama a 'GetXXXX(k) que nos devuelve el array solicitado del array User(). OJO: del array User, no del array Sudoku (Matriz, la llamas tu).
Luego que devuelve ese array es el parámetro de entrada para invocar a la función Presencia(array), y la salida de esta, que también devuelve un array pero de 10 elementos, es usada como la entrada de la función Ausencia(array) que devuelve finalmente un valor buleano.
Es equivalente a esto mismo (pero requiere entonces declarar un array dentro de la función, para recibir y pasar a la siguiente función y más líneas de código).
Citar
array tipo byte Arr() // sería antes del bucle.
Arr = GetFila(k)
Arr = Presentes(arr)
ausentes = Ausencia(arr)
Si ausentes = false Devolver False //y salir de la función
Arr = GetFila(k)
Arr = Presentes(arr)
ausentes = Ausencia(arr)
Si ausentes = false Devolver False //y salir de la función
Esta función ya la conoces, es equivalente a la segunda parte de unificar arrays:
Código:
Array byte = Funcion Presencia(array tipo byte Arr() )
array tipo byte Tmp(0 a 9) // 10 elementos.
Bucle para k = 0 a 8
tmp( arr(k)) = arr(k)
Fin Bucle
Devolver Tmp
Fin Funcion
Esta función también la conoces, pero aquí en vez de devolver el array con los ausentes, devolvemos si hay o no ausentes (o la cantidad de ausentes y en destino convertirlo en False si es mayor que 0).
Código:
Buleano = Funcion Ausencia(array tipo byte Presentes() )
Bucle para k desde 1 a 9 //OJO: 10 elementos, hasta 9
Si (Presentes(k) <> k) luego
Devolver FALSE //y salir de la función
Fin si
Fin bucle
Devolver True
Fin funcion
Un último consejo... mira de optimizar el código una vez te funciones bien. Estas dos funciones, podrían llamar a otras que realicen el trabajo 8ya en el código previo) y aquí solo evaluar el resultado y devolverlo...
No pongo el pseudocódigo de lo que sería la función: 'ValidarSudokuDeUnaSolaSolucion', porque es bastante sencilla.
Ya sabes que puedes ponerle el nombre que quieras a las funciones, siempre que el propio nombre revele su intencionalidad... sin necesidad de llegar a ser tan largo y explícito como: 'ValidarSudokuDeUnaSolaSolucion', que tiene por objeto además ser auto-explicativo... podría ser 'ValidarSolucionSimple' y el otro 'ValidarSolucionMultiple'...
Recuerda que deberás tener varios arrays, como mínimo estos 3:
- El de la Solución (que se genera cuando creas el sudoku).
- El de Pistas (que es una selección-extracción de la solución).
- Y el del Usuario (que inicialmente es copia del array Pistas), y que es donde el usuario va introduciendo los valores que él mismo decida.
Por tanto tras crear el Sudoku (la solución, el array Matriz) satisfactoriamente), tras ello invoca a sendas funciones para inicializar ambos arrays adicionales (pistas y User). Crear el de User también conviene que sea una función aparte, porque si el usuario reclama 'Resetear' la partida, entre otras cosas deberás volver a clonar el array Pistas() en User().