//numero mas pequeño disponible entre las opciones public bool masPequeña(GrillaSudoku grilla, out int r, out int c, out int numElegido) { bool[] minList = new bool[10]; int numCh, minR, minC, minimoNumeroElegido, i, j; bool mal, result; minimoNumeroElegido = 10; minR = 0; minC = 0; for (i = 1; i < 10; i++) { minList[i] = false; } mal = false; i = 0; while (!mal && i < 9) { j = 0; while (!mal && j < 9) { if (grilla.grilla[i, j] == 0) { numCh = ListaPosible(i, j, grilla); if (numCh == 0) { mal = true; } else { if (numCh < minimoNumeroElegido) { minimoNumeroElegido = numCh; list.CopyTo(minList, 0); minR = i; minC = j; } } } j++; } i++; } if (mal || minimoNumeroElegido == 10) { result = false; r = 0; c = 0; numElegido = 0; } else { result = true; r = minR; c = minC; numElegido = minimoNumeroElegido; minList.CopyTo(list, 0); } return(result); }
//rellenar public void rellena(GrillaSudoku grid) { bool algunCambio = false; int numElegido; do { algunCambio = false; for (int i = 0; i < 9; i++) { for (int j = 0; j < 9; j++) { if (grid.grilla[i, j] == 0) { numElegido = ListaPosible(i, j, grid); if (numElegido == 1) { grid.setearCeldaUsuario(i, j, PrimerVerdadero()); algunCambio = (grid.grilla[i, j] != 0); } } } } } while (algunCambio == true && !estaResuelto(grid)); }
// retorna true si estaEnFila, estaEnColumna y estaEn3x3 return false public bool EsPosible(GrillaSudoku g, int fila, int col, int valor) { bool result; result = (!estaEnFila(g, fila, valor) && !estaEnColumna(g, col, valor) && !estaEnEl3x3(g, fila, col, valor)); return(result); }
//devuelve grilla resuelta public GrillaSudoku InicializarGrilla() { //rellena aleatoreamente primera fila y columna GrillaSudoku tempGrilla = new GrillaSudoku { }; //grilla temporaria int fila = 0; int col = 0; int nuevoVal; //valor para poner dentro de grilla List <int> setValor = new List <int>(Enumerable.Range(-9, 9)); //rango de numeros List <int> setValor2 = new List <int>(); Random rnd = new Random(); //numero random int numRandom = 0; numRandom = rnd.Next(0, 8); nuevoVal = setValor[numRandom]; tempGrilla.inicializarCeldas(fila, col, nuevoVal); setValor.Remove(nuevoVal); for (fila = 1; fila < 9; fila++) { numRandom = rnd.Next(0, setValor.Count); nuevoVal = setValor[numRandom]; setValor2.Add(nuevoVal); setValor.Remove(nuevoVal); tempGrilla.inicializarCeldas(fila, col, nuevoVal); } fila = 0; for (col = 1; col < 3; col++) { numRandom = rnd.Next(0, setValor2.Count); nuevoVal = setValor2[numRandom]; while ((nuevoVal == tempGrilla.grilla[1, 0] || (nuevoVal == tempGrilla.grilla[2, 0]))) { numRandom = rnd.Next(0, setValor2.Count); nuevoVal = setValor2[numRandom]; } setValor2.Remove(nuevoVal); tempGrilla.inicializarCeldas(fila, col, nuevoVal); } for (col = 3; col < 9; col++) { numRandom = rnd.Next(0, setValor2.Count); nuevoVal = setValor2[numRandom]; setValor2.Remove(nuevoVal); tempGrilla.inicializarCeldas(fila, col, nuevoVal); } do { solucionadorSudoku = new SolucionadorSudoku(); solucionadorSudoku.resolverGrilla((GrillaSudoku)tempGrilla.Clone(), false); GrillaSolucion = solucionadorSudoku.solucion; } while (GrillaSolucion == null || GrillaSolucion.estaEnBlanco()); PermaGrilla = borrarCuadros(GrillaSolucion); return(PermaGrilla); }
/// chequea si el valor esta en la columna public bool estaEnColumna(GrillaSudoku grilla, int col, int valor) { bool result = false; for (int i = 0; i < 9; i++) { result = result || (Math.Abs(grilla.grilla[i, col]) == valor); } return(result); }
// chequea si el valor esta en la fila public bool estaEnFila(GrillaSudoku grid, int fila, int valor) { bool result = false; for (int i = 0; i < 9; i++) { result = result || (Math.Abs(grid.grilla[fila, i]) == valor); } return(result); }
//toma el sudoku resuelto y le saca algunos numeros public GrillaSudoku borrarCuadros(GrillaSudoku grillaResuelta) { GrillaSudoku grillaTemporal; GrillaSudoku guardarCopia; bool unico = true; int totalDeNumSacados = 0; int intentos = 0; int espaciosEnBlancoDeseados; //cantidad de espacios en blanco deseados int simetria = 0; grillaTemporal = (GrillaSudoku)grillaResuelta.Clone(); Random rnd = new Random(); switch (dificultad) //cantidad de espacios en blancos deseados segun dificultad { case Difficulty.Easy: //easy espaciosEnBlancoDeseados = 10; break; case Difficulty.Medium: //medium espaciosEnBlancoDeseados = 25; break; case Difficulty.Hard: //hard espaciosEnBlancoDeseados = 40; break; default: espaciosEnBlancoDeseados = 60; break; } simetria = rnd.Next(0, 2); //selecciona simetria random do { guardarCopia = (GrillaSudoku)grillaTemporal.Clone(); grillaTemporal = borrarAzar(grillaTemporal, simetria, ref totalDeNumSacados); //borra 1 o 2 cuadros depende simetria solucionadorSudoku = new SolucionadorSudoku(); unico = solucionadorSudoku.resolverGrilla((GrillaSudoku)grillaTemporal.Clone(), true); if (!unico) { grillaTemporal = (GrillaSudoku)guardarCopia.Clone(); intentos++; } } while ((totalDeNumSacados < espaciosEnBlancoDeseados) && (intentos < 1000)); grillaResuelta = grillaTemporal; grillaResuelta.Termina(); return(grillaResuelta); }
//clona objeto interfaz clone public object Clone() { //abilito el clonado GrillaSudoku p = new GrillaSudoku(); for (int i = 0; i < Max; i++) { for (int j = 0; j < Max; j++) { p.inicializarCeldas(i, j, grilla[i, j]); } } return(p); }
/// borra cuadros al azar public GrillaSudoku borrarAzar(GrillaSudoku grillaTemporal, int simetria, ref int cantidadDeBorrados) { Random rnd = new Random(); //genero num random int fila = rnd.Next(0, 8); //selecciono fila random int column = rnd.Next(0, 8); //y columna while (grillaTemporal.grilla[fila, column] == 0) // no borro lo que ya este borrado { fila = rnd.Next(0, 8); column = rnd.Next(0, 8); } grillaTemporal.inicializarCeldas(fila, column, 0); cantidadDeBorrados++; //incremento la contador switch (simetria) { case 0: //vertical if (grillaTemporal.grilla[fila, 8 - column] != 0) { cantidadDeBorrados++; } grillaTemporal.inicializarCeldas(fila, 8 - column, 0); break; case 1: //horizontal if (grillaTemporal.grilla[8 - fila, column] != 0) { cantidadDeBorrados++; } grillaTemporal.inicializarCeldas(8 - fila, column, 0); break; case 2: //diagonal if (grillaTemporal.grilla[column, fila] != 0) { cantidadDeBorrados++; } grillaTemporal.inicializarCeldas(column, fila, 0); break; default: //diagonal if (grillaTemporal.grilla[fila, 8 - column] != 0) { cantidadDeBorrados++; } grillaTemporal.inicializarCeldas(column, fila, 0); break; } return(grillaTemporal); }
//se recorren las celdas para comprobar si esta resuelto //retorna verdadero si esta resuelto falso sino public bool estaResuelto(GrillaSudoku grid) { bool result = true; int r, c; r = 0; while (result == true && r < 9) //chequeo todas las filas { c = 0; while (result == true && c < 9) //chequeo todas las columnas { //si uno esta vacio tiro falso result = (result && grid.grilla[r, c] != 0); c++; } r++; } return(result); }
public int ListaPosible(int row, int col, GrillaSudoku g) { int contador = 0; LimpiarLista(); for (int i = 1; i < 10; i++) { if (EsPosible(g, row, col, i) == true) { list[i] = true; contador++; } else { list[i] = false; } } return(contador); }
//retorna modo de juego estndar public ModoDeJuego(Difficulty diff) : base(diff) { grillaSudoku = new GrillaSudoku(); solucionadorSudoku = new SolucionadorSudoku(); generadorSudoku = new generarSudoku(diff); generadorSudoku.InicializarGrilla(); base.solucion = generadorSudoku.GrillaSolucion.grilla; base.mask = generadorSudoku.PermaGrilla.grilla; grillaUsuario.Initialize(); for (int i = 0; i < 9; i++) { for (int j = 0; j < 9; j++) { mask[i, j] = -mask[i, j]; grillaUsuario[i, j] = mask[i, j]; } } }
//determina en que 3x3 esta //volores /// [0, 0] [0, 1] [0, 2] /// [1, 0] [1, 1] [1, 2] /// [2, 0] [2, 1] [2, 2] public bool estaEnEl3x3(GrillaSudoku g, int fila, int col, int valor) { int fMasChica; int cMasChica; fMasChica = 3 * grupoDeNumeros(fila); //indice de la fila mas pequeña cMasChica = 3 * grupoDeNumeros(col); //indice de la columna mas pequeña bool result = false; for (int i = fMasChica; i < fMasChica + 3; i++) //chequea todas las filas en la subgrilla { for (int j = cMasChica; j < cMasChica + 3; j++) //chekea todas las columnas en la subgrilla { if (Math.Abs(g.grilla[i, j]) == valor) { result = true; } } } return(result); }
//resolver grilla public bool resolverGrilla(GrillaSudoku g, bool chequearUnicidad) { GrillaSudoku grilla = new GrillaSudoku(); grilla = (GrillaSudoku)g.Clone(); int i, eleccion, r, c, numeroElegido; bool bien, got_one, resuelto, result; got_one = false; recursiones++; rellena(grilla); if (estaResuelto(grilla)) { if (numSolns > 0) { stop = true; result = false; } else { numSolns++; final[numSolns] = (GrillaSudoku)g.Clone(); result = true; solucion = grilla; } } else { if (!masPequeña(grilla, out r, out c, out numeroElegido)) { result = false; } else { i = 1; bien = false; got_one = false; while (!bien && i <= numeroElegido) { eleccion = PickeoUno(); list[eleccion] = false; grilla.setearCeldaUsuario(r, c, eleccion); if (recursiones < max) { resuelto = (resolverGrilla(grilla, chequearUnicidad)); } else { resuelto = false; } if (stop == true) { bien = true; got_one = true; } else { got_one = (got_one || resuelto); if (!chequearUnicidad) { bien = got_one; } } i++; } result = got_one; } } return(result); }