Mejorado post clase
unknown
python
a year ago
8.6 kB
1
Indexable
Never
# Rodrigo Sampedro Casis import random def display_board(board): #funcion para pintar el tablero # para acceder a la primera casila (fila 0 columna 0) segunda casilla (fila 0 columna 1) ... print("\n") for c in range(0,3): print(f"{board[c][0]} | {board[c][1]} | {board[c][2]} {c*3+1} | {c*3+2} | {c*3+3} ") if(c != 2): print("-","*","-","*","-"," -","*","-","*","-") print("\n") print("--------------------------------------------------------------------------") def enter_move(board): #funcion para que el usario introduzca su movimiento move_done = False while(not move_done): introduccion = input("Introduzca un numero del 1 - 9 para la posicion del movimiemto.") # check numerico if( introduccion.isnumeric()): movimiento = int(introduccion) # posibles movimientos libres posibles_movimientos = list_free_fields(board) # check es un numero entre 1-9 y esta disponible if(0<movimiento<10 and (movimiento in posibles_movimientos)): do_movement(board, movimiento,"Jugador", "X") move_done = True else: # indicar al usuario que se ha equivocado en el numero o no esta disponible print("Has introducido un numero invalido, recuerde 1-9 y que este disponible.") def list_free_fields (board): # funcion para devolver los posibles movimientos disponibles lista_vacia=[] for posicion in range (1,10): fila = (posicion - 1) // 3 columna = (posicion -1 ) % 3 #si la casilla esta vacia " " es un movimiento disponible if(board[fila][columna]==" "): lista_vacia.append(posicion) return lista_vacia def victory_for(board, sign): #funcion para saber si la jugada hace tre en raya for i in range (0,3): # comprobamos jugadas en horizontal y en vertical if(board[i][0]==board[i][1]==board[i][2]==sign or board[0][i]==board[1][i]==board[2][i]==sign): return True #c comprobamos jugadas en diagonal if(board[0][0]==board[1][1]==board[2][2]==sign or board[0][2]==board[1][1]==board[2][0]==sign): return True else: return False def do_movement(board, movement, player, sign): # funcion que ejecuta el movimiento en el tablero pasado por argumento fila = (movement - 1) // 3 columna = (movement -1 ) % 3 board[fila][columna] = sign # encaso de movimiento real lo muestra por pantalla if(player!="simulacion"): print(f"Movimiento de la {player} {movement}") def draw_move(board): # funcion que ejecuta el movimiento del 'computador' en el tablero #busca todos los posibles movimientos casillas_vacias = list_free_fields(board) # la inteligencia (algoritmica) busca jugada mas interesante para O movimiento = inteligencia(board, "0", "X") # ejecuta movimiento en el tablero do_movement(board, movimiento,"Computadora", "0") # muestra tablero con movimiento ejecutado display_board(board) def inteligencia(board, jugador1, jugador2): # funcion donde incluir el algoritmo de inteligencia del computador # posibles jugadas del tablero casillas_vacias = list_free_fields(board) jugadas_ganadoras = [] jugadas_tapon = [] # ejecutamos cada uno de los posibles jugadas para evaluarlas # 1º objetivo es ganar en la jugada # 2º objetivo es evitar que el usuario gane, ya que la computadora siempre juega segunda # 3º objetivo obtener una jugada estrategica # 4º si no hay un objetivo alcanzable, jugar con aleatoriedad for movimiento in casillas_vacias: # creamos una copia del tablero sobre la que hacer # simulaciones de jugadas simulacion = [row[:] for row in board ] # Ganar => simular si movimiento gana computadora do_movement(simulacion, movimiento,"simulacion", jugador1) if (victory_for(simulacion, jugador1)==True): # retornar jugada ganadora jugadas_ganadoras.append(movimiento) # Taponar => simular si el usuario ganar con movimiento simulacion = [row[:] for row in board ] do_movement(simulacion, movimiento,"simulacion", jugador2) if (victory_for(simulacion, jugador2)==True): # taponar jugada futura del usuario jugadas_tapon.append(movimiento) # Ejecuto jugadas segun mis objetivos if(len(jugadas_ganadoras)>0): return jugadas_ganadoras[0] if(len(jugadas_tapon)>0): return jugadas_tapon[0] # checkear que el centro esta libre, punto estrategico if( 5 in casillas_vacias): # con esta inteligencia si el usuario no escoge el centro # la maquina nunca pierde, puesto que el usuario ya no puede hacer # doble jugada ganadora return 5 #elseif TODO: si juego primero, estrategia de esquinas para doble jugada ganadora # esta jugada no es aplicable puesto que lamaquina siempre juega 2º else: # Simulacionas de jugadas a 2 iteraciones # (esto hace a la maquina algo mas inteligente, para priorizar aquellas # jugadas donde un error humano a 2 iteraciones, de las que no existe amenaza # # Por lo tanto este else puede ser obviado por una inteligencia menos lista # pero mas rapida for movimiento in casillas_vacias: if(len(casillas_vacias)>3): # simulo movimiento actual # + una iteracion mas de inteligencia simulacion = [row[:] for row in board ] do_movement(simulacion, movimiento,"simulacion", jugador1) # calculo siguiente mejor movimiento de mi adversario # que es ganar el o taponarme a mi movimiento2 = inteligencia(simulacion, jugador2, jugador1) simulacion2 = [row[:] for row in simulacion ] # evaluo si su movimiento es un tapon do_movement(simulacion2, movimiento2,"simulacion", jugador1) if (victory_for(simulacion2, jugador1)==True): # retornar jugada ganadora a 2 iteraciones return movimiento # Si su jugada es aleatoria o me gana el a 2 iteraciones no me interesa # este movimineto, pasar al siguiente posibilidad # si no existe un objetivo alcanzable random entre las posibles jugadas return casillas_vacias[random.randint(0, len(casillas_vacias)-1)] def jugar(): # esta funcion es el punto de entrada # ejecuta la creacion del tablero y los mensajes iniciales # y realiza las llamadas a las diferentes funciones para ejecutar el juego # creacion de tablero e inicio del juego tablero = [[" " for c in range(3)] for d in range(3)] print("Vamos a jugar al 3 en raya!!!") display_board(tablero) # TODO: interesante mejora, flip a coin y que pueda empezar la maquina o el usuario # codigo recurrente hasta que gane unjugador o no existan mas jugadas no_box = False while(not no_box): # juega usuario enter_move(tablero) # comprobar si usuario gana if (victory_for(tablero, "X")==True): print (" \n *** Has ganado *** \n") break # comprobar si es la ultima jugada por que no quedan casillas if (len(list_free_fields(tablero)) == 0): print (" \n *** Empate *** \n") break # juega la computadora draw_move(tablero) # comprobar si la computadora ha ganado if (victory_for(tablero, "0")==True): print ("Has perdido") break #comprobar si existen mas juegadas por parte del usuario # como el usuario siempre juega primero y el tablero es impar # y se juega a bloques de 2 jugadas # este caso no se puede dar, solo util si la maquina puede jugar primero #if(len(list_free_fields(tablero)) == 0): # print ("Empate") # no_box = True # mostramos final del tablero display_board(tablero) # llamada ala funcion principal del script jugar () jugar()