algoritmo de poda ALPHA-BETA de Python Tic Tac Toe y código específico del algoritmo de fuerza bruta
#!/usr/bin/env python
'''Tic tac toe en python, Minimax con poda alfa-beta.'''
importar sys
importar aleatorio
importar getopt
# Tablero: matriz de 9 int, numerados posicionalmente así:
# 0 1 2
# 3 4 5
# 6 7 8
# Posiciones conocidas en el tablero
WINNING_TRIADS = ((0, 1, 2), (3, 4, 5), (6, 7, 8), (0, 3, 6), (1, 4, 7),
(2, 5, 8), (0, 4, 8), (2, 4, 6))
PRINTING_TRIADS = ((0, 1, 2), (3, 4, 5), (6, 7, 8))
# El orden en el que se comprueban las ranuras para detectar la ausencia de una ficha de jugador:
SLOTS = (0, 1, 2, 3, 4, 5, 6, 7, 8)
# Valores de uso interno Elegidos para que el "ganador" de un juego terminado
# tenga un valor adecuado, ya que X minimiza y O maximiza
. # el valor del tablero (la función board_value() define "valor")
# Internamente, la computadora siempre reproduce Os, aunque los marcadores[]
# la matriz puede cambiar según - Bandera de línea de comando r.
X_token = -1
Open_token = 0
O_token = 1
# Cadenas para salida: marcadores del jugador , frase para el final del juego
MARKERS = ['_', 'O', 'X']
END_PHRASE = ('empate', 'gana', 'pérdida ')
HUMANO = 1
COMPUTADORA = 0
def valoración_tablero(tablero, jugador, siguiente_jugador, alfa, beta):
'''Evaluación dinámica y estática de la posición del tablero.'''
# Evaluación estática - valor para next_player
wnnr = ganador(tablero)
if wnnr != Open_token:
# No es un empate
o un movimiento a la izquierda: alguien ganó
return wnnr
elif not legal_move_left(board):
# Empate - no quedan movimientos
return 0 # Cat
# Si el flujo de control llega aquí, aún no hay ganador, ni empate.
# Verifica todos los movimientos legales para "jugador"
para moverse en SLOTS:
if board[move] == Open_token:
board[move] = player
val = board_value(board, next_player , player, alpha, beta)
board[move] = Open_token
if player == O_token: # Maximizando jugador
if val > alpha: p>
alfa = val
si alfa >= beta:
devuelve beta
más: # jugador X_token, minimizando
si val < beta:
beta = val
si beta <= alfa:
devuelve alfa
si jugador == O_token :
retval = alfa
else:
retval = beta
return retval
def print_board(tablero ):
'''Imprime el tablero en formato legible por humanos.
Llamado con el tablero actual (matriz de 9 entradas).
'''
para fila en PRINTING_TRIADS:
para agujero en fila:
imprimir MARCADORES[tablero[agujero]],
imprimir
def legal_move_left(board):
''' Devuelve Verdadero si queda un movimiento legal, Falso si no '''
para el espacio en SLOT.
S:
if board[slot] == Open_token:
return True
return False
def ganador(tablero) :
''' Devuelve -1 si X gana, 1 si O gana, 0 para un juego de gatos,
0 para un juego sin terminar.
Devuelve la primera "ganancia" que encuentre, así que verifique después de cada movimiento.
Tenga en cuenta que las elecciones inteligentes de X_token, O_token, Open_token
hacen que esto funcione mejor.
'' '
para tríada en WINNING_TRIADS:
triad_sum = tablero[triad[0]] + tablero[triad[1]] + tablero[triad[2]]
if triad_sum == 3 o triad_sum == -3:
return board[triad[0]] # Aprovecha los valores "_token"
return 0 p>
def determine_move(board):
''' Determina el próximo movimiento de Os. Comprueba que queda un movimiento legal antes de llamar.
Elige aleatoriamente un único movimiento de cualquier grupo. de movimientos con el mismo valor.
'''
best_val = -2 # 1 menos que el mínimo de O_token, X_token
my_moves = [] p>
para moverse en SLOTS:
if board[move] == Open_token:
board[move] = O_token
val = board_value( board, X_token, O_token, -2, 2)
board[move] = Open_token
print "Mi movimiento", movimiento, "provoca un", END_PHRASE[val] p>
if val > best_val:
best_val = val
my_moves = [movimiento]
if val == best_val:
my_moves.append(movimiento)
>
return random.choice(my_moves)
def recv_human_move(board):
''' Encapsula la recepción y validación de entradas humanas.
Llama con configuración actual del tablero. Devuelve
un int de valor 0..8, el movimiento del Humano.
'''
looping = True
mientras se realiza el bucle:
prueba:
inp = input("Tu movimiento: ")
yrmv = int(inp)
si 0 <= yrmv <= 8:
if board[yrmv] == Open_token:
looping = False
else:
imprimir "Plaza ya ocupada."
else:
imprimir "Mal movimiento, no hay donut."
excepto EOFError:
sys.exit(0)
excepto NameError:
print "No es 0-9, inténtalo de nuevo."
excepto SyntaxError:
imprime "No es 0-9, inténtalo de nuevo."
si está en bucle:
print_board(board)
regresa yrmv
def use(progname):
'''Llame con el nombre del programa para explicar su uso.'''
print progname + ": Tic Tac Toe en python"
print "Uso:", nombre del programa, "[-h] [-c] [-r] [-x] [-X]"
print "Flags:"
print "-x, -X: imprime este mensaje de uso, luego sal."
print "-h: el humano va primero (predeterminado)" p>
print "-c: la computadora va primero"
print "-r: la computadora es X, el humano es O"
print "La c
o computadora O y el humano juega X por defecto."
def main():
'''Llamar sin argumentos desde el contexto __main__.'''
Pruebe:
opts, args = getopt.getopt(sys.argv[1:], "chrxX",
["humano", "computadora", "ayuda"])
excepto getopt.GetoptError:
# imprimir información de ayuda y salir:
uso(sys.argv[0])
sys .exit(2)
next_move = HUMAN # Humano va primero por defecto
para opt, arg in opts:
if opt == "-h" :
next_move = HUMANO
if opt == "-c":
next_move = COMPUTADORA
if opt == "- r":
MARKERS[-1] = 'O'
MARKERS[1] = 'X'
si opta por participar ("-x", "-X", "--help"):
uso(sys.argv[0])
sys.exit(1)
# Inicial estado del tablero: todos los espacios abiertos.
tablero = [Open_token, Open_token, Open_token, Open_token, Open_token,
Open_token, Open_token, Open_token, Open_token]
# Máquina de estado para decidir quién va a continuación y cuándo termina el juego.
# Esto permite dejar que la computadora o el humano vayan primero.
while legal_move_left(board) and ganador(board) = = Open_token:
print_board(board)
if next_move == HUMAN and legal_move_left(board):
humanmv = recv_human_move (tablero)
tablero[humanmv] = X_token
next_move = COMPUTADORA
if next_move == COMPUTADORA y legal_move_left(tablero):
mymv = determine_move(tablero)
print "Yo elijo", mymv
tablero[mymv] = O_token
next_move = HUMAN
print_board(board)
# Estado final del tablero/ganador y resultado de felicitación.
prueba: p>
# "Ganaste" nunca debería aparecer en la salida: el programa
# siempre debería al menos dibujar.
print ["El gato consiguió el juego", "Yo ganó", "Ganaste"][ganador(tablero)]
excepto IndexError:
print "Error realmente grave, el ganador es", ganador(tablero)
sys.exit(0)
#-------
if __name__ == '__main__':
prueba:
main()
excepto KeyboardInterrupt:
sys.exit(1)