... pero llegue a un punto que no te entiendo y es la parte final de rellenar el sudoku como lo tienes en el siguiente codigo:
...por que tu hablas de codigo previo y codigo despues ???
//código previo
....el código intermedio (omitido por brevedad)
.... // código después...
Puse 'código previo' y 'código después', para
no volver a poner la función completa... En ese tramo, lo que te indicaba era que justo esa parte (de la función) es la que se encarga de que si la 'obtención' de valores llega a un punto donde se bloquea, esa parte CRUCIAL, es la que dando 1, ó 2 pasos atrás, permite salir del bloqueo:
1 paso atrás: elimina toda la fila actual y la rehace.
2 pasos atrás: deshace también la fila previa, si tras deshacer 10 veces la fila actual, no logra avanzar (salir del bloqueo)... un bloqueo 'persistente', se debe a que no deja muchas opciones para la línea actual.
1- cual es ese array sudoku y para que sirve ? no lo entiendo la verdad
2- yo estoy trabajando con una matriz bidimensional y en mi funcion generadoraleatorio() es donde supuestamente lo lleno(Segun mi forma de hacerlo) pero no se en que lugar estaria metiendo este codigo que te muestro arriba el tuyo,
1 - Es el nombre que yo le he dado al array que guarda los valores... tu lo llamas matriz[][] y lo usas de modo bidimensional (filas y columnas, 9x9), yo lo llamo sudoku y usa índices (0 a 80).
2 - Yo hice una función llamada RellenarSudokuAlAzar, que es función principal para generar el sudoku por completo, es desde aquí donde se llama a la segunda función principal (para un solo valor al azar) y en esa donde se llama al resto...
Repongo la función completa, esta función la puse en el 'Respùesta #2' de este hilo (IMPORTANTE: lee los comentarios en el pseudocódigo):
Funcion RellenarSudokuAlAzar()
Entero Fila, columna
Byte Valor, Intentos
Fila=0 // la primera fila, la podrías obtener al azar completamente en ese caso marcar aquí 1, para comenzar en la fila 1, la 0 no va a requerir todas las comprobaciones que pueden requerir las siguientes.
Hacer '// esto es fila, puede ser un bucle que va de 0 a 8
Intentos = 0
Columna = 0
Hacer
Valor = SeleccionarValorAzar(Columna, Fila) //la función que obtiene un valor de cada vez.
Si (Valor>0) luego
Sudoku((Fila * c_Nueve) + Columna) = valor //Sudoku() es el array que mantiene internamente los valores.
Columna +=1
Si no
// Borra los valores de la fila actual
Bucle para k desde 0 a columna
Sudoku((Fila * c_Nueve) + k) = 0
Fin bucle
// Tras 10 intentos en la misma fila, borramos también la fila previa
Intentos += 1
Si (Intentos = 10) luego
Si (Fila > 0) luego // no podemos retroceder a filas más atrás que la primera.
Fila = (Fila - 1) // Borramos también la fila anterior (y si sucede otra vez, la previa, etc...)
Bucle para k desde 0 To c_Ocho
Sudoku((Fila * c_Nueve) + k) = 0
Fin Bucle
Fin si
Intentos = 0
Fin si
Columna = 0
Fin si
Repetir Mientras (Columna <9)
Fila +=1
Repetir Mientra (Fila<9)
Fin Funcion
// Al término de esta función se podría dibujar los valores en el tablero para verificar visualmente el resultado.
3- por otro lado tengo muchas dudas con la funcion de tomar ausentes por que pones como parametro un out NumAusentes
Array Byte = Funcion TomarAusentes(Array Byte Presentes(), Out Entero NumAusentes)
no entiendo por que pones ese valor ahi, o bueno creo saberlo, lo haces para tener el indice de ese vector pero lo que no se es por que tenerlo de parametro si al llamarlo de otra funcion como lo haces en
Array byte = GetArrayAusentes(Entero X, Entero Y, Out Entero NumAusentes)
ese valor no lo utilizas de ninguna manera o por lo menos no lo veo que lo hagas para mi ese valor por parametro no sirve por que el dato que se utiliza es es que devuelve la funcion como tal.
Te aclaro... esta función devuelve un array. El array tiene 9 elementos, pero necesitamos también devolver otro valor. el de cuantos valores en ese array son 'útiles' (detrás de esos valores útiles hay ceros, no nos interesan).
El parámetro es de salida, es decir es devuelve por referencia (por puntero, una dirección de memoria).
Un ejemplo: Imagina una lista de 9 alumnos para el carnet de conducir... se examinan y aprueban solo 3, se devuelve una lista, con sus nombres, pero es preciso saber cuantos son. La lista sigue teniendo 9 elementos, no viene a cuento crear una nueva lista con exactamente los conductores aprobados, la reutilizamos.
Si no sabes pasar un parámetro por referencia, todavía puedes solucionarlo en tu código, recorriendo el array hasta que se encuentre un valor vacío (cero).
Es decir había una lista de 9 alumnos inscritos, creamos otra del mismo tamaño 8por si todos aprobaban), pero luego resulta que aprueban 3, ó 5 o 6, o todos o ninguno)... entonces en la lista entregada leemos nombres, con cada uno leído sumamos 1, cuando no haya más en la lista de aprobados, sabemos ya CUANTOS alumnos aprobaron. 3,5,6,todos, ninguno, etc...
Y porqué necesitamos saber cuantos valores 'útiles' (valores ausentes) tiene la lista?. Pués porque ahora vamos a sortear entre ellos, el elegido será el que se ponga en la casilla.
Si hay 5 valores ausentes (útiles), (similar a los alumnos aprobados) y ocupan los puestos del 0 al 4, nosotros luego vamos a elegir al azar entre 0 y 4.
SIIIIIIII... elegimos ún índice, porque las funciones aleatorias no saben elegir al azar un valor 2,5,6,9, solo saben elegir un valor dentro de un rango dado, y dentro de ese rango los valores contenidos son elegibles. Si el 3,4,7 y8 quedan fuera del sorteo, significa que no debn ser elegibles, luego toca asignarles un número a los que si optan y luego por ese número (índice en el array), sabemos que valor salió elegido.
Imagina que son esos alumnos, podríamos hacer papelitos con sus nombres, pero OH, nuestro sistemá es matemático (míralo como si tuvieras un bingo de juguete con 100 bolitas, sacas todas y dejas una por cada alumno aprobado) y a cada bola se le asigna un nombre: La bola 0, para Juan, la bola 1 para Luis, la bola 2 par aandrés,etc... entonces hhaces mover el bombo, extraes la bola y cantas la que sale: Bola 2.... a qui
én corresponde? a Andres.... luego Andres salió elegido al azar...
Justo eso esa parte final, es la que hacen las líneas tras la función Tomarausentes:
Este trozo de código es un extracto al final de la función: "SeleccionarValorAzar"
// OJO: si el array queda vacío <----------- HAY UN BLOQUEO.
Si (n=0) luego devolver 0 //y salir de la función tras devolver
// Finalmente se toma un valor al azar entre 0 y n-1, que representa el indice del array Azar. Este array tiene exclusivamente los números que no aparecen ni en la fila, ni en columna, ni en bloque.
k = Aleatorio( entre 0 y n-1)
Devolver Azar(k) //ha salido la bola K, devlver el valor contenido en ese índice (si fuera un alumno, sería su nombre).
La verdad no me queda muy claro eso voy a colocar el codigo que tengo solo para que me ayudes a depurar errores pero solo faltaria que me explicaras eso que te pido para poder hacer las funciones de valor azar y la de permitido o admisible no entiendo el por que tu tienes otras mas tampoco.
Creo que debería quedarte todo claro ya...
Verás tu función "GeneradorAleatorio" sería equivalente a la que yo llamo: "RellenarSudokuAlAzar"....
Debe tener 2 bucles, uno por filas y otro interno para columnas. Dentro de ese es que en cada cilo se invoca "SeleccionarValorAzar(fila, columna)" esperando que se le devuelva un valor.
Si es mayor que 0 se asigna al array que mantiene los valores (tu llamas 'Matriz' a tu array, yo le llamo directamente 'Sudoku' a mi array)
Pero si el valor obtenido de regreso es 0, significa que hay una situación de bloqueo. Hay que eliminar la fila actual completa (se suma un intento y si se alcanzan 10 antes de poder completar la fila, se elimina también la fila anterior).
----------------------------------------------
Te comento por encima si veo bien tus funciones, pero debes probarlas siempre.
Yo solo reviso la lógica, que es la parte que el IDE (seguramente uses Eclipse), no puede decirte nada...
- GeneradorAleatorio: Llámala como prefieras, pero esta función, impleméntala tomando como referencia la que yo llamo "RellenarSudokuAlAzar". Justo te acabo de dar unas palabras al respecto... y el pseudocódigo de la misma te lo he vuelto a poner completo, también más arriba en este mensaje.
public static void GeneradorAleatorio() {
- GetFila: OK
public static int [] GetFila(int matriz[][], int fila) {
- GetColumna: OK
public static int [] GetColumna(int matriz [][], int columna) {
- GetCaja: OK, pero puede optimizarse saber a qué bloque (caja), nos estamos refiriendo (ya te comenté)
public static int [] GetCaja(int matriz[][], int filas, int columnas) {
- unificarArray: OK, ahora sí...
public static int[] unificarArray (int filas[], int columnas[], int caja[]) {
- TomarAusentes: CASI, te falta devolver el valor de k (yo lo hago por referencia como un parámetro). Si no lo devuelves de ninguna manera, deberás volver a calcular dicho valor en un bucle tras esta función (más arriba ya te comenté esto)
public static int [] TomarAusentes (int unificado[]){
La parte comentada es donde iria las funciones que me faltan por entender.
OK, en otro mensaje (un poco más tarde, ahora tengo cosas que hacer), te desgrano ambas funciones (son dos, no?): SeleccionarValorAzar y RellenarSudokuAlAzar