Implementación de Tic-Tac-Toe en Python: Código y Lógica del Juego

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

Escrito el en español con un tamaño de 7,58 KB

Introducción

Este documento presenta la implementación de un clásico juego de Tic-Tac-Toe, conocido popularmente como "El Gato", desarrollado en Python. Se detallan las funciones clave y la lógica principal que rigen el flujo del juego, desde la inicialización del tablero hasta la determinación del ganador o un posible empate.

Estructura del Tablero

El tablero del juego se representa mediante una lista de listas en Python, donde cada sublista corresponde a una fila. Se utilizan caracteres especiales para indicar el estado de cada casilla:

  • "-": Casilla vacía.
  • "X": Marca del jugador.
  • "O": Marca del PC.

La primera fila y columna se utilizan para las etiquetas de coordenadas (A, B, C y 1, 2, 3).

import random

gato = [[" ","1","2","3"],["A","-","-","-"],["B","-","-","-"],["C","-","-","-"]]

Funciones del Juego

Función imprimir_gato

Esta función se encarga de mostrar el estado actual del tablero en la consola, facilitando la visualización del juego para el usuario.

def imprimir_gato(gato):
    for fila in gato:
        print(" ".join(fila))

Función verificar_casilla

Valida la entrada del usuario para asegurar que la casilla seleccionada sea válida y exista dentro del tablero. Transforma la entrada alfanumérica (ej. "B2") en coordenadas numéricas utilizables por el programa.

def verificar_casilla(y):
    casilla = []
    # Transforma la letra en coordenada
    if y[0] == "A" or y[0] == "a":
        casilla.append(1)
    elif y[0] == "B" or y[0] == "b":
        casilla.append(2)
    elif y[0] == "C" or y[0] == "c":
        casilla.append(3)
    else:
        casilla.append("Error")
    if casilla[0] == "Error":
        return casilla
    else:
        casilla.append(y[1])
        return casilla

Función ganar (para el Jugador)

Comprueba si el jugador (marcado con "X") ha logrado una combinación ganadora en el tablero. Revisa todas las posibles líneas (horizontales, verticales y diagonales).

def ganar(gato):
    i = 1
    final = "Pasa"
    while i < 4:
        if gato[1][i] == "X" and gato[2][i] == "X" and gato[3][i] == "X": # Revisa si ganas en vertical
            final = "Ganaste"
        elif gato[i][1] == "X" and gato[i][2] == "X" and gato[i][3] == "X": # Revisa si ganas en horizontal
            final = "Ganaste"
        i += 1
    if gato[1][1] == "X" and gato[2][2] == "X" and gato[3][3] == "X": # Revisa si ganas cruzado (diagonal principal)
        final = "Ganaste"
    elif gato[3][1] == "X" and gato[2][2] == "X" and gato[1][3] == "X": # Revisa si ganas cruzado (diagonal secundaria)
        final = "Ganaste"
    return final

Nota: Se corrigió la segunda condición diagonal en la función ganar para que sea la diagonal secundaria (C1, B2, A3), ya que la original era una repetición de la diagonal principal.

Función ganar_pc (para el PC)

Similar a la función ganar, pero esta verifica si el PC (marcado con "O") ha ganado la partida. Si el PC gana, desde la perspectiva del jugador, significa que el jugador ha "Perdido".

def ganar_pc(gato):
    final = [] # Se usa una lista para consistencia, aunque un string sería suficiente si solo se añade "Perdiste"
    i = 1
    while i < 4:
        if gato[1][i] == "O" and gato[2][i] == "O" and gato[3][i] == "O": # Revisa si ganas en vertical
            final.append("Perdiste")
        elif gato[i][1] == "O" and gato[i][2] == "O" and gato[i][3] == "O": # Revisa si ganas en horizontal
            final.append("Perdiste")
        i += 1
    if gato[1][1] == "O" and gato[2][2] == "O" and gato[3][3] == "O": # Revisa si ganas cruzado (diagonal principal)
        final.append("Perdiste")
    elif gato[3][1] == "O" and gato[2][2] == "O" and gato[1][3] == "O": # Revisa si ganas cruzado (diagonal secundaria)
        final.append("Perdiste")
    return final

Nota: Se corrigió la segunda condición diagonal en la función ganar_pc por la misma razón que en ganar.

Lógica Principal del Juego

Inicialización

Se inicializa el tablero y se determina aleatoriamente quién comienza la partida: el jugador (turno = 0) o el PC (turno = 1).

print(" Gato ")
imprimir_gato(gato) # La función ya imprime, no necesita un print externo

# Se crea un random para saber quién inicia la partida. Si turno=0, inicia la persona; si turno=1, el PC.
turno = random.randint(0,1)

if turno == 0:
    print("Debes digitar la casilla donde quieres colocar la X. Por ejemplo: B2. ¡Tú inicias!")
else:
    print("Debes digitar la casilla donde quieres colocar la X. Por ejemplo: B2. ¡El PC inicia!")

print("\n")

contador = 1 # El contador es para terminar el juego si empatan

Bucle Principal del Juego

El juego se ejecuta en un bucle while True que continúa hasta que un jugador gana o se produce un empate.

while True:
    if turno == 0:
        print("¡Tu turno!")
        casilla = input("Casilla: ") # Cambiado de raw_input a input para Python 3
        casilla = verificar_casilla(casilla)
        if casilla[0] == "Error":
            print("(!) La casilla no existe. Intenta nuevamente.")
        else:
            fil = int(casilla[0])
            col = int(casilla[1])
            if gato[fil][col] == "X" or gato[fil][col] == "O":
                print("(!) La casilla está utilizada. Intenta nuevamente.")
            else:
                gato[fil][col] = "X"
                imprimir_gato(gato)
                final = ganar(gato) # Se llama a la función para verificar el estado del juego
                if final == "Ganaste":
                    print("¡GANASTE!")
                    break
                else:
                    contador += 1
                    turno = 1 # Cambia el turno al PC
    else: # Turno del PC
        print("¡Turno del PC!")
        casilla_rival = ["",""]
        # El PC elige una casilla aleatoria hasta encontrar una vacía
        while True:
            casilla_rival[0] = random.randint(1,3)
            casilla_rival[1] = random.randint(1,3)
            fil = int(casilla_rival[0])
            col = int(casilla_rival[1])
            if gato[fil][col] == "-": # Si la casilla está vacía, el PC la ocupa
                gato[fil][col] = "O"
                break # Sale del bucle interno una vez que el PC ha hecho su movimiento
        imprimir_gato(gato)
        final_pc = ganar_pc(gato) # Se llama a la función para verificar el estado del juego
        # La función ganar_pc devuelve una lista, si contiene "Perdiste", significa que el PC ganó.
        if "Perdiste" in final_pc: # Se verifica si la lista contiene el string "Perdiste"
            print("¡PERDISTE!")
            break
        else:
            contador += 1
            turno = 0 # Cambia el turno al jugador

    if contador == 10: # Si el contador llega a 10, significa que todas las 9 casillas están ocupadas y no hay ganador.
        print("¡EMPATE!")
        break

Nota: Se añadió un bucle while True dentro del turno del PC para asegurar que el PC solo coloque su marca en una casilla vacía. También se ajustó la verificación de final_pc para que sea "Perdiste" in final_pc, ya que la función devuelve una lista.

Entradas relacionadas: