TB Logo
Juego de Sudoku en terminal (C)

Juego de Sudoku en terminal (C)

oct 2020
Tiempo dedicado: ~20 h
Ver en GitHub
Etiquetas:
Aplicación de terminalAlgoritmosEstructuras de datos
Habilidades:
C
C

Sudoku en terminal

Este es un proyecto pequeño que hice cuando estaba aprendiendo C y quería algo concreto para practicar algoritmos, manejo de entrada y una estructura de programa “de verdad”.
Es un Sudoku para terminal: puedes introducir un tablero manualmente o generar uno aleatorio, y después resolverlo tú o dejar que el programa lo resuelva.
Puedes ver el código en GitHub.

Vista previa de Sudoku en terminal
Vista previa de Sudoku en terminal

Qué hace

El programa permite algunos flujos sencillos: generar un tablero, jugar manualmente introduciendo coordenadas y (opcionalmente) pedirle al solucionador que termine el tablero.
También dediqué tiempo al renderizado en terminal para que el tablero sea legible e incluya coordenadas de filas/columnas, usando caracteres Unicode de líneas y cajas.

Funciones principales

  • Generación aleatoria de tableros.
  • Resolución manual introduciendo coordenadas x/y y un número.
  • Solucionador automático (backtracking).
  • Validación de jugadas: sin duplicados en fila, columna o bloque (3 x 3), y solo permite rellenar celdas vacías.

Cómo funciona el solucionador

El solucionador automático usa backtracking: intenta completar el tablero paso a paso y, cuando llega a una contradicción, “retrocede” y prueba otra opción.
En la práctica repite el mismo patrón: elige una celda vacía, prueba los números del 1 al 9 que cumplen las reglas (fila, columna y bloque (3 x 3)), y continúa de forma recursiva hasta completar el tablero.

Para hacerlo más rápido (y porque quería experimentar), el solucionador no se queda con la primera celda vacía: busca primero la celda vacía con el menor número de candidatos posibles.
Esto reduce ramas inútiles y normalmente acelera la resolución, porque obliga al algoritmo a enfrentarse antes a las celdas más “difíciles”.

El algoritmo

  1. Buscar una celda vacía (un 0 en mi tablero).
  2. Si no quedan celdas vacías, el Sudoku está resuelto.
  3. Para la celda vacía elegida, calcular qué números del 1 al 9 están permitidos:
    • Que no estén ya en la misma fila.
    • Que no estén ya en la misma columna.
    • Que no estén ya en el mismo bloque (3 x 3).
  4. Probar cada número permitido:
    • Colocarlo en la celda.
    • Resolver recursivamente el resto del tablero.
    • Si más adelante falla, volver a poner la celda a 0 y probar el siguiente número.
  5. Si ningún número funciona, retroceder a la decisión anterior.

Pseudocódigo breve

resolver(tablero): celda = buscar_celda_vacia(tablero) si no celda: retornar verdadero # Sudoku resuelto para numero en numeros_permitidos(celda, tablero): colocar_numero(celda, numero, tablero) si resolver(tablero): retornar verdadero quitar_numero(celda, tablero) # Retroceder retornar falso # Ningún número funcionó

Generación aleatoria de tableros

El modo de “tablero aleatorio” empieza colocando un pequeño número de valores aleatorios válidos y después usa el solucionador para completar el tablero hasta obtener una solución completa.
Luego elimina un buen número de celdas (volviéndolas a 0) para crear un puzle jugable.

En concreto, el código:

  • Inicializa la aleatoriedad con srand(time(NULL)).
  • Coloca 10 números válidos al azar.
  • Resuelve el tablero por completo.
  • Elimina 55 celdas rellenas.

Como era un proyecto de aprendizaje, el generador no garantiza una solución única en cada caso.

Lo que aprendí (y límites)

Este proyecto me enseñó muchas bases: recursión, backtracking y cómo estructurar programas pequeños en C con funciones claras y una validación cuidadosa de la entrada.

Limitaciones / cosas que mejoraría

  • El generador puede crear puzles que no tengan solución única (perfectamente válido para una demo de aprendizaje, pero no ideal para un generador “real”).
  • Si lo hiciera de nuevo, separaría mejor la UI de la lógica del solucionador (varios archivos, estado más limpio).
  • No hay ajuste de nivel de dificultad para los puzles generados, lo que podría ser una mejora interesante.