Apuntes_Python/01_curso/Modulo_2/2-5b_evaluacion_gate.py
2022-12-24 22:41:20 -03:00

234 lines
9.8 KiB
Python

""" 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()