Desarrollo de un Juego de Sudoku en Python: Lógica y Estructura de Código

Enviado por Chuletator online y clasificado en Informática y Telecomunicaciones

Escrito el en español con un tamaño de 10,57 KB

Desarrollo de un Juego de Sudoku en Python: Lógica y Estructura de Código

Este documento presenta el código fuente de una implementación básica de un juego de Sudoku en Python. Se detallan las funciones principales encargadas de la visualización del tablero, la interacción del usuario para ingresar valores y la validación de las reglas del juego.

1. Importación de Módulos

Se requiere un módulo externo, presumiblemente llamado sudoku (corregido de sudoky para mayor claridad y convención), que maneja la lógica interna del tablero, como la carga inicial y la manipulación de celdas.

import sudoku # Se asume que 'sudoky' es un módulo llamado 'sudoku'

2. Funciones Principales del Juego

2.1. Función mostrarSudoku()

Esta función se encarga de imprimir el estado actual del tablero de Sudoku en la consola, formateándolo para una mejor visualización, incluyendo las líneas divisorias de las subcuadrículas 3x3.

def mostrarSudoku(): # Nombre de función ajustado de 'mostrarSudoky' a 'mostrarSudoku' por convención.
    i = 0
    print("   012 345 678")
    print("   --- --- ---")
    while i < 9:
        print(i, "|", end="")
        j = 0
        while j < 9: # j<9:
            print(sudoku.obtener(i, j), end="") # Se asume 'sudoky' es 'sudoku'
            # print(end="" "|") # Comentario original
            # print(sudoku.obtener(i,j),"|") # Comentario original
            # print("|") # Comentario original
            # print(sudoku.obtener(i,j), end="") # Comentario original: cachar como cerrar el sudoku |
            if (j % 3 == 2):
                print(" ", end="")
            j += 1
        print("")
        if (i % 3 == 2):
            print("   --- --- ---")
        i += 1

2.2. Función cambiar_casilla()

Permite al usuario ingresar un valor en una celda específica del tablero. Incluye validaciones para asegurar que el valor ingresado sea válido según las reglas básicas del Sudoku (rango, celda no pre-llenada, valor único en fila y columna).

def cambiar_casilla():
    num_fila = int(input("Fila: ")) # Ajuste de mayúsculas
    num_col = int(input("Columna: ")) # Ajuste de mayúsculas
    valor = int(input("Valor: ")) # Ajuste de mayúsculas

    # Validación de rango de entrada
    if num_fila not in range(0, 9) or num_col not in range(0, 9) or valor not in range(0, 9):
        print("Solo números entre 0 y 8.") # Ajuste de puntuación y mayúsculas
        return # Se añade un 'return' para salir si la entrada es inválida

    valido = 1 # Flag de validación

    # Validación de celda ya completada
    if sudoku.obtener(num_fila, num_col) != 0: # Se asume 'sudoky' es 'sudoku'
        print("Casilla ya completada.") # Ajuste de puntuación y mayúsculas
        valido = 0

    # Validación de valor en la fila
    i = 0
    while i < 9:
        if (sudoku.obtener(num_fila, i)) == valor: # Se asume 'sudoky' es 'sudoku'
            print("Este valor ya existe en esta fila.") # Ajuste de puntuación y mayúsculas
            valido = 0
        i += 1

    # Validación de valor en la columna
    i = 0
    while i < 9:
        if (sudoku.obtener(i, num_col)) == valor: # Se asume 'sudoky' es 'sudoku'
            print("Este valor ya se encuentra en esta columna.") # Ajuste de puntuación y mayúsculas
            valido = 0
        i += 1

    # Aplicar el cambio si todas las validaciones iniciales son correctas
    if valido == 1:
        sudoku.definir(num_fila, num_col, valor) # Se asume 'sudoky' es 'sudoku'
    # else: # Comentario original
    #    print ("error") # Comentario original
    i = 0 # Variable 'i' sin uso aparente aquí, se mantiene por "no cortar texto"

2.3. Función numero_cuadrante() y Validación de Cuadrante

Esta sección del código intenta implementar la lógica para determinar el cuadrante 3x3 al que pertenece una celda y, posteriormente, validar si un valor ya existe dentro de ese cuadrante. Es importante notar que la implementación original presenta algunas inconsistencias lógicas y está incompleta en su definición de cuadrantes. Además, la variable valor utilizada en la validación del cuadrante no es un parámetro de la función, lo que causaría un error de ejecución (NameError) si se intentara usar directamente.

## Para hacer restricción de cuadrante
def numero_cuadrante(num_fila, num_col):
    # Esta función parece tener un doble propósito:
    # 1. Determinar las coordenadas de inicio (a, b) del cuadrante 3x3.
    # 2. Realizar la validación del valor dentro de ese cuadrante.
    # La implementación original está incompleta para todos los cuadrantes y
    # la lógica de validación está mezclada con la determinación del cuadrante.

    # Determinación de las coordenadas de inicio del cuadrante
    if num_fila in range(0, 3):
        if num_col in range(0, 3):
            a = 0
            b = 0
            ## Cuadrante 1
        elif num_col in range(3, 6):
            a = 0
            b = 3
            ## Cuadrante 2
        else: # num_col in range(6, 9)
            a = 0
            b = 6
    elif num_fila in range(3, 6):
        if num_col in range(0, 3):
            a = 3
            b = 0
            ## Cuadrante 4
        # Faltan los cuadrantes 5 y 6 en la lógica de 'a' y 'b'.
        # Para una implementación completa, se necesitarían más bloques 'elif' y 'else'.
        # Por ejemplo:
        # elif num_col in range(3, 6):
        #     a = 3
        #     b = 3
        # else: # num_col in range(6, 9):
        #     a = 3
        #     b = 6
    # Faltan los cuadrantes para num_fila in range(6, 9).
    # elif num_fila in range(6, 9):
    #     if num_col in range(0, 3):
    #         a = 6
    #         b = 0
    #     elif num_col in range(3, 6):
    #         a = 6
    #         b = 3
    #     else: # num_col in range(6, 9):
    #         a = 6
    #         b = 6

    # Comentario original: ## Ahí sigues tu
    # La siguiente sección intenta validar el valor en el cuadrante.
    # Sin embargo, la variable 'valor' NO ES UN PARÁMETRO de esta función,
    # lo que causaría un 'NameError' si se ejecutara tal cual.
    # Además, la función retorna la cadena "hola" en caso de error, lo cual no es una práctica estándar.
    # Para que esta validación funcione, 'valor' debería ser un parámetro de la función.
    # Se asume que 'sudoky' es 'sudoku'.
    # La lógica de validación del cuadrante podría ser más eficiente con un bucle anidado.
    # Por ejemplo:
    # for r in range(a, a + 3):
    #     for c in range(b, b + 3):
    #         if sudoku.obtener(r, c) == valor: # 'valor' necesitaría ser un parámetro
    #             print("Este valor ya existe en este cuadrante.")
    #             return "hola" # Manteniendo el comportamiento original de retorno

    # Se mantiene la estructura original del código, aunque con las observaciones anteriores.
    # NOTA: 'valor' no está definido en este ámbito, lo que generaría un error si se ejecutara.
    if (valor == (sudoku.obtener(0 + a, 0 + b)) or valor == (sudoku.obtener(0 + a, 1 + b)) or valor == (sudoku.obtener(0 + a, 2 + b))
        or valor == (sudoku.obtener(1 + a, 0 + b)) or valor == (sudoku.obtener(1 + a, 1 + b)) or valor == (sudoku.obtener(1 + a, 2 + b))
        or valor == (sudoku.obtener(2 + a, 0 + b)) or valor == (sudoku.obtener(2 + a, 1 + b)) or valor == (sudoku.obtener(2 + a, 2 + b))):
        print("Error en el cuadrante.") # Ajuste de puntuación
        return "hola" # Retorno de cadena "hola" según el código original

    # La siguiente parte del código parece ser una continuación de la lógica de validación
    # que se ejecutaría después de llamar a numero_cuadrante.
    # Sin embargo, 'valido', 'num_fila' y 'num_col' no están definidos en este ámbito global.
    # Esto sugiere que estas líneas estaban destinadas a estar dentro de 'cambiar_casilla'
    # o en el bucle principal, y se han movido aquí por error o como parte de un desarrollo.
    # Se mantienen en su posición original para no "cortar el texto", pero se señala su problemática.
    # NOTA: 'num_fila', 'num_col' y 'valido' no están definidos aquí, lo que generaría errores si se ejecutara.
    if numero_cuadrante(num_fila, num_col) == "hola": # Esta llamada recursiva es problemática y causaría un NameError.
        valido = 0 # 'valido' no está definido aquí.
    if valido == 1: # 'valido' no está definido aquí.
        print(sudoku.definir(num_fila, num_col, valor)) # 'valor' no está definido aquí.

3. Bucle Principal del Juego

El juego se ejecuta en un bucle continuo, permitiendo al usuario interactuar con el tablero hasta que decida salir. Se carga un tablero inicial según el nivel de dificultad elegido.

a = int(input("Elija el nivel a jugar: 1-Fácil 2-Medio 3-Difícil: ")) # Ajuste de puntuación
sudoku.cargarTablero(a) # Se asume que 'sudoky' es 'sudoku'

jugando = 1
while jugando == 1:
    mostrarSudoku() # Se asume que 'mostrarSudoky' es 'mostrarSudoku'
    b = int(input("¿Qué desea hacer ahora: 1-Ingresar un valor 2-Salir del juego? ")) # Ajuste de puntuación y mayúsculas

    if (b == 1):
        cambiar_casilla()
        # La siguiente línea intenta llamar a 'numero_cuadrante'.
        # Sin embargo, 'num_fila' y 'num_col' son variables locales de 'cambiar_casilla()'
        # y no están definidas en este ámbito global, lo que causaría un 'NameError'.
        # Además, la validación del cuadrante debería integrarse en 'cambiar_casilla()'
        # o ser una función de validación independiente que reciba todos los parámetros necesarios.
        numero_cuadrante(num_fila, num_col) # ERROR: 'num_fila' y 'num_col' no están definidos aquí.

        # Bloque de código comentado original, se mantiene.
        # jugando=2
        # j=0
        # while j<9:
        #    i=0
        #    while i<9:
        #        if sudoku.obtener(i,j)==1: #and jugando==2: # Se asume que 'sudoky' es 'sudoku'
        #            jugando=1
        #        i+=1
        #    j+=1
    else:
        jugando = 0
        print("¡Hasta pronto!") # Ajuste de puntuación y exclamación

    # Este bloque es inalcanzable si 'jugando' se establece a 0 en el 'else' anterior.
    # Si la intención era que 'jugando' pudiera ser 2 para indicar victoria,
    # la lógica de cambio de 'jugando' a 2 y su posterior reevaluación necesitaría ser revisada.
    if jugando == 2:
        print("¡Felicitaciones!") # Ajuste de puntuación y exclamación

Entradas relacionadas: