Haremos el juego Tic Tac Toe en Python, para ejemplificar el uso de funciones en Python.
Éste artículo está disponible en video. Míralo aquí: https://youtu.be/w0LqU99RRy8
Vamos a utilizar la librería deque que nos permite crear y utilizar una cola en Python (Martelli, 2006). Una cola es una lista de datos a la que le podemos aplicar el método rotate, para rotar los elementos a la izquierda o a la derecha. Ésto nos servirá para cambiar (rotar) el turno del jugador.
También crearemos el tablero, que será una multilista o lista de listas.
from collections import deque turno = deque(["0", "X"]) tablero = [ [" ", " ", " "], [" ", " ", " "], [" ", " ", " "], ]
Crearemos una función para mostrar el tablero. Ésta imprimirá (utilizando un for) la multilista que contiene el tablero.
Otra función será la de actualizar el tablero. Ésta función agregará una X o un O a un espacio dentro de la multilista.
La función rotar turno utiliza el método rotate para rotar los valores de X y O y devuelve el que queda en la posición [0].
def mostrar_tablero(): print("") for fila in tablero: print (fila) def actualizar_tablero(posicion, jugador): tablero[posicion[0]][posicion[1]] = jugador def rotar_turno(): turno.rotate() return turno[0]
Tenemos una función para procesar la posición, ésta convierte una cadena dada como “1,1” en una lista que contendrá los valores [0,0]. Ésto es necesario porque la multilista empieza en 0 y no en 1 (como lo ve el usuario).
La función posicion_correcta determina si la posición dada contiene un valor correcto. Por ejemplo, la posición dada “4,4” no sería correcta, pues no existe la línea 4 en el juego.
def procesar_posicion(posicion): fila, columna = posicion.split(",") return [int(fila)-1, int(columna)-1] def posicion_correcta(posicion): if 0 <= posicion[0] <= 2 and 0 <= posicion[1] <= 2: if tablero[posicion[0]][posicion[1]] == " ": return True return False
La siguiente función recibe como valor de parámetro el jugador (“X” o “O”) y revisa la multilista analizando todo el tablero.
Primero compara las filas, luego las columnas y por último las diagonales. No compara si existe empate entre los jugadores (se deja como ejercicio al lector).
def ha_ganado(j): #compara las filas del tablero if tablero[0] == [j,j,j] or tablero[1] == [j,j,j] or tablero[2] == [j,j,j]: return True #compara las columnas elif tablero[0][0] == j and tablero[1][0] == j and tablero[2][0] == j: return True elif tablero[0][1] == j and tablero[1][1] == j and tablero[2][1] == j: return True elif tablero[0][2] == j and tablero[1][2] == j and tablero[2][2] == j: return True #compara las diagonales elif tablero[0][0] == j and tablero[1][1] == j and tablero[2][2] == j: return True elif tablero[0][2] == j and tablero[1][1] == j and tablero[2][0] == j: return True return False
La función principal, a la que llamamos juego, utiliza un ciclo While infinito para preguntar al usuario la posición (fila, columna) en el tablero en la que desea dejar la marca del jugador en turno. El ciclo finaliza con break cuando recibe la cadena ‘salir’ o cuando un jugador gana el partido. Se emplea un bloque try except para convertir la cadena dada (por ejemplo, ‘1,1’) en una lista. Si se introduce un valor diferente, (como abcxyz) al no poder convertirlo a dos elementos de lista separándolos por comas, se generará un error que será atrapado en el bloque except. Se invoca la función principal juego() misma que llama a todas las demás.
def juego(): mostrar_tablero() jugador = rotar_turno() while True: posicion = input("Juega {}, elige una posicion (fila, columna) de 1 a 3. 'salir' para salir".format(jugador)) if posicion == 'salir': print ("Adios!!!") break try: posicion_l = procesar_posicion (posicion) except: print ("Error, posicion {} no es válida. ".format(posicion)) continue if posicion_correcta(posicion_l): actualizar_tablero(posicion_l, jugador) mostrar_tablero() if ha_ganado(jugador): print ("Jugador de {} ha ganado!!!".format(jugador)) break jugador = rotar_turno() else: print ("Posicion {} no válida".format(posicion)) juego()
Éste artículo está disponible en video. Consúltalo aquí: