""" Deberás programar el juego TA-TE-TI. Cuando el programa comienza a correr, en la pantalla aparece el tablero de TA-TE-TI (de 3x3) y un input que permite al usuario elegir el símbolo “X” o el símbolo “O”. Las “X” empiezan. El usuario debe elegir la posición del tablero (esta posición debe ser correcta y no debe estar ocupada) donde poner el símbolo en el tablero y el sistema valida si el juego termina con un ganador o en empate. Si no hay ganador o la partida no terminó todavía en empate, el juego continúa preguntando al otro usuario que seleccione la posición del tablero dónde quiere poner su símbolo y así siguiendo hasta que la partida termine con un ganador o en empate. Notas: Representar el tablero como una matriz de 3x3. El juego termina en empate cuando el tablero está completo y no hay ganadores.""" # Este archivo ha sido creado con fines didacticos y como entrega final del 2do modulo del Curso Aprende a Programar # en Python, dictado por la Universidad Austral, atravez de Coursera # @Autor: devfzn@gmail.com import random import os from time import sleep # Limpia pantalla, funciona en algunos sistemas (Shell + Python 3.8.2, Windows 10 Python3.8.4, IDLE no, y en # py-charm (click derecho en el archivo (2 opciones mas abajo de Run, entrar en EDIT y seleccionar ejecutar # en Emulador de Terminal, en vez de Python console.) clear = lambda: os.system('clear') if os.name == 'posix' else os.system('cls') limpiar_pantalla = True """ Creación de matriz base""" #matriz = [['a1', 'b1', 'c1'], ['a2', 'b2', 'c2'], ['a3', 'b3', 'c3']] matriz = [['|_','|_','|_'], ['|_','|_','|_'], ['|_','|_','|_']] # Creacción de dicionario vacío y lista de llaves. master, llaves = {}, [x+y for x in 'abc' for y in '123'] # Preguntas para solicitar entradas de usuario lado = '\tEscribe \'o\' para jugar con \'O\',\n\to \'x\' para jugar con \'X\',\n\t(\'X\' hace la primera jugada)\n\t> ' salir = '\tJugar Otra? (si/no)\n\t> ' jugada = '\tIngresa tu jugada (ej. a2)\n\t> ' tit_V = 'Ganaste, Felicitaciones!' tit_P = ' Has perdido' # Lista con tuplas de condiciones para ganar o perder el juego. ganadoras = [('a1', 'b1', 'c1'), ('a2', 'b2', 'c2'), ('a3', 'b3', 'c3'), ('a1', 'a2', 'a3'), ('b1', 'b2', 'b3'), ('c1', 'c2', 'c3'), ('a1', 'b2', 'c3'), ('c1', 'b2', 'a3')] def actualizar_matriz(): """ Actualiza los valores en la matriz según los valores en diccionario maestro :return: None """ x, y = 0, 0 # Variables para indices de matriz tablero for valor in master.values(): # Recorre los valores del diccionario if not y < 3: # Limite indice columnas y = 0 # Reinicio contador columnas x += 1 # Autoincremento de fila al llegar a 3ra columna matriz[y][x] = valor # Asigna el valor del diccionario a la matriz (casilla) y += 1 # Autoincremento de columna def dibujar_tablero(*frase): """ Muestra en pantalla un string pasada como argumento, coordenadas y matriz de juego :param frase: titulo a mostrar según circunstancia :return: None """ if limpiar_pantalla: clear() print('\n\t', *frase, '\n\n\t\t a b c') for x in range(len(matriz)): print('\t\t', end=str(x+1)) for y in range(len(matriz[x])): print(matriz[x][y], end='') print('|') print('\n') # #####################################** ANIMACION **################################################################ # saludo = ['\n\tBienvenido al Clasico ', '\n\n\n\t\t\"GATO!\"'] jugadas = [[0, 0], [1, 2], [2, 0], [1, 0], [1, 1], [2, 2], [0, 2]] def parp_text(repets, *texto): print(len(texto)) x, sec = 0, True while x < repets: for txt in texto: for tx in txt: clear() print('\n\t', tx) sleep(0.7) x += 1 sleep(1) def animacion(): actualizar_matriz() for x in range(len(jugadas)): if x % 2 == 0: matriz[jugadas[x][0]][jugadas[x][1]] = '|X' else: matriz[jugadas[x][0]][jugadas[x][1]] = '|O' dibujar_tablero('\"devfzn@gmail.com\"') sleep(0.5) animacion() parp_text(2, saludo) ######################################################################################################################## def input_usr(pregunta, respuestas): """ Solicita una entrada al usuario, recive 1 string y una lista de string :param pregunta: string Pregunta a realizar :param respuestas: [string] Lista de posibles respuestas en mayúscula :return: 'string' input de usuario validado """ resp = '' # Variable que recibe entrada de usuario while resp not in respuestas: # Valida respuesta según 'respuestas' resp = input(pregunta).upper() # Asignación entrada de usuario (mayusculas forzadas) return resp jugar = True # Variable que gobierna el ciclo principal (Juego) while jugar: # Ciclo principal global turno # for llave in llaves: # Recorre las llaves y asgina '|_'(vacío) a cada item master[llave] = '|_' slave = master.copy() # Copia superficial del diccionario maestro actualizar_matriz() # Poblar matríz con los valores del diccionario maestro dibujar_tablero(' Elige el lado X - O') # Imprime matríz en pantalla global p1 p1 = input_usr(lado, ['x', 'X', 'o', 'O']) # Asignación de entrada de usuario, P1 (Player 1) titulo = 'P1 jugando con -> ' + p1 cambio = lambda x: 'O' if x == 'X' else 'X' # Función anónima retorna el símbolo opuesto al evaluado X,O global pc pc = cambio(p1) # Asignación de símbolo a jugador PC (Player Computer) turno = 0 # Contador de turnos jugados dibujar_tablero(titulo) def turno_p1(): """ Función que recibe una entrada de usuario y la valida según la copia de las llaves del diccionario maestro. Actualiza el valor en el diccionario maestro con el symbolo seleccionado por el jugador PC y e xtrae la copia de 'slave' :return: None """ jp1 = input_usr(jugada, list(x.upper() for x in list(slave.keys()))).lower() slave.pop(jp1) master[jp1] = '|' + p1 def turno_pc(): """ Función que selecciona una llave al azar de la copia del diccionario maestro y actualiza a este último con el simbolo del jugador PC. Despues del turo nro. 2 evalúa si hay algún espacio estrategico, donde existen dos simbolos iguales, pone el tercero, priorizando los pares de symbolos afines con el bando asignado. :return: None """ if turno > 2: falta, hay_par = (), False for pos in ganadoras: a, b, c = master[pos[0]], master[pos[1]], master[pos[2]] if '|_' != a == b != c == '|_': falta = (a, pos[2]) hay_par = True if a == pc + '|_': break elif '|_' != a == c != b == '|_': falta = (a, pos[1]) hay_par = True if a == pc + '|_': break elif '|_' != c == b != a == '|_': falta = (c, pos[0]) hay_par = True if c == pc + '|_': break if hay_par: jpc = falta[1] else: jpc = ''.join(random.choice(list(slave.keys()))) else: jpc = ''.join(random.choice(list(slave.keys()))) slave.pop(jpc) master[jpc] = '|' + pc def eval_term(): """ Función que evalua si se cumplen las condiciones para terminar la partida. Compara los valores el diccionario 'maestro' según las llaves en las tuplas, de la lista 'ganadaoras'. Asigna un titulo y un valor al booleano 'termino' :return: None """ global titulo global termino for g in ganadoras: test = master[g[0]] test2 = '|' + p1 if '|_' != test == master[g[1]] == master[g[2]]: termino = True titulo = tit_V if test2 == '|X' == test else tit_V if test2 == '|O' == test else tit_P if turno > 8 and not termino: termino, titulo = True, '\t EMPATE' X = p1 == 'X' # Booleano indica si jugador 1 es 'X' termino = False # Booleano que gobierna ciclo de jugadas while not termino: # Ciclo de jugadas turno_p1() if X else turno_pc() # Alterna el turno del Player1 y PC, segun 'X' X = not X # Alterna el booleano 'X' turno += 1 eval_term() actualizar_matriz() dibujar_tablero(titulo) resp = input_usr(salir, ['N', 'NO', 'S', 'SI']) jugar = resp in 'SI' # Actualización del booleano que gobierna while principal autor = ['', '\n\n\t "devfzn@gmail.com\"'] parp_text(4, autor) #exit() #quit()