¿Existe tal algoritmo donde, si se le da una potencia de procesamiento infinita, una computadora podría jugar al ajedrez perfectamente para que nunca pierda?
Si es así, ¿dónde puedo encontrar un pseudocódigo para él?
¿Existe tal algoritmo donde, si se le da una potencia de procesamiento infinita, una computadora podría jugar al ajedrez perfectamente para que nunca pierda?
Si es así, ¿dónde puedo encontrar un pseudocódigo para él?
Respuestas:
¿Existe un algoritmo? Sí. Según el Teorema de Zermelo , hay tres posibilidades para un juego de dos jugadores de información perfecta y determinista finito como el ajedrez: o el primer jugador tiene una estrategia ganadora, o el segundo jugador tiene una estrategia ganadora, o cualquiera de los jugadores puede forzar un empate. No sabemos (todavía) para qué sirve el ajedrez. (Las damas, por otro lado, se han resuelto : cualquier jugador puede forzar un empate).
Conceptualmente, el algoritmo es bastante simple: construye un árbol de juego completo , analiza los nodos de hoja (las posiciones de finalización del juego) y realiza el movimiento inicial ganador, renuncia u ofrece un empate.
El problema radica en los detalles: hay aproximadamente 10 43 posiciones posibles y un número aún mayor de movimientos (la mayoría de las posiciones se pueden alcanzar de más de una manera). Realmente necesita su computadora infinitamente poderosa para aprovechar esto, ya que una computadora que puede aprovechar este algoritmo no puede caber en el universo conocido o no finalizará la computación hasta algún momento después de que termine el universo.
Ver https://en.wikipedia.org/wiki/Endgame_tablebase .
Con una potencia de computadora infinita, uno podría construir una mesa para la posición inicial y resolver el ajedrez .
En la práctica, solo las posiciones con hasta siete "hombres" (peones y piezas, contando a los reyes) se han resuelto utilizando supercomputadoras actuales, por lo que estamos muy lejos de resolver el ajedrez. La complejidad del problema aumenta exponencialmente con el número de piezas.
Si realmente tuviera un poder de procesamiento infinito , tal algoritmo sería realmente trivial para escribir. Como el ajedrez tiene un número finito de estados posibles, en teoría podrías simplemente recorrerlos todos hasta encontrar un camino de juego perfecto. Sería terriblemente ineficiente, pero si tienes un poder de procesamiento infinito , no importaría.
Para abordar directamente la pregunta: sí, existe tal algoritmo. Se llama minimax. (Las bases de tablas del final del juego se generan mediante el uso de este algoritmo (¡hacia atrás!), Pero el viejo y simple algoritmo minimax es todo lo que necesitas). Este algoritmo puede jugar perfectamente cualquier juego de suma cero de dos jugadores. Encuentra pseudocódigo aquí:
https://en.wikipedia.org/wiki/Minimax
Tenga en cuenta que las variantes de este algoritmo son utilizadas por los programas de ajedrez informáticos modernos.
No solo existe un algoritmo para jugar al ajedrez perfecto, es posible escribir un programa corto que (dado recursos infinitos) jugará perfectamente cualquier juego determinista de dos jugadores de duración finita y conocimiento perfecto.
El motor del juego ni siquiera necesita conocer las reglas del juego que está jugando. Todo lo que necesita es una representación opaca de un "estado del juego" y funciones que (a) dado cualquier estado del juego, proporcione una lista de los siguientes estados legales del juego y (b) dado un estado del juego, decida si es una victoria para el jugador 1 , una victoria para el jugador 2, un empate o no es un estado final.
Dadas esas funciones, un algoritmo recursivo simple "resuelve" el juego.
Este hecho ha sido aludido en respuestas anteriores por chessprogrammer (minimax) y por Acccumulation (que proporciona una versión del programa en python).
Escribí tal programa hace más de 20 años. Lo probé jugando ceros y cruces (tic-tac-toe si eres estadounidense). Efectivamente, jugó un juego perfecto.
Por supuesto, esto caerá rápidamente en cualquier computadora imaginable para cualquier juego serio. Debido a que es recursivo, efectivamente está construyendo todo el árbol de juego en la pila, por lo que obtendrá un "desbordamiento de pila" (juego de palabras muy intencionado) antes de acercarse a analizar los 10 ^ 123 estados de ajedrez mencionados en otras respuestas. Pero es divertido saber que, en principio, este pequeño programa haría el trabajo.
Para mí, esto también dice algo interesante sobre la IA: por más que "inteligencia" creas que es exhibida por Deep Blue, o Go Zero, o de hecho por un humano jugando al ajedrez o Go, hay un sentido en el que estos juegos tienen un trivial, exactamente computable óptimo soluciones El desafío es cómo obtener una solución buena aunque no óptima en un tiempo razonable.
Ignoraré las posibilidades de sorteos o secuencias infinitas de movimientos por simplicidad. Una vez que se entiende el algoritmo, no es particularmente difícil extenderlo a esos casos.
Primero, algunas definiciones:
Cualquier movimiento que gane el juego para el jugador que hace ese movimiento es un movimiento ganador.
Cualquier movimiento que pierda el juego para el jugador que hace ese movimiento es un movimiento perdedor.
Cualquier movimiento que deje al otro jugador con al menos un movimiento ganador también es un movimiento perdedor. (Dado que el oponente puede hacer ese movimiento y forzar una pérdida).
Cualquier movimiento que deje al otro jugador solo con movimientos perdedores también es un movimiento ganador. (No importa qué movimiento haga tu oponente, ganarás).
Una estrategia perfecta significa siempre hacer movimientos ganadores si queda alguno y renunciar cuando uno solo tiene movimientos perdedores restantes.
Ahora, es trivial escribir una estrategia perfecta. Simplemente explote todas las secuencias de movimiento posibles e identifique movimientos ganadores / perdedores. Ignorando el estancamiento, esto eventualmente identificará cada movimiento como un movimiento ganador o un movimiento perdedor.
Ahora, la estrategia es trivial. Mira todos tus movimientos posibles. Si quedan movimientos ganadores, tome uno y gane. Si solo quedan movimientos perdedores, renuncia, ya que tu oponente puede forzarte a perder.
No es difícil ajustar la estrategia para incluir la posibilidad de un punto muerto.
Actualización : en caso de que no esté claro cómo esto identifica cada movimiento como un movimiento ganador o perdedor, considere:
n
al número de movimientos en el juego de ajedrez más largo posible. (Estamos ignorando secuencias ilimitadas por ahora, aunque incluirlas no es difícil).n
anteriores que debamos tener en cuenta.n-1
movimientos anteriores es un movimiento ganador o un movimiento perdedor ya que los n
movimientos finalizan el juego más largo.n-2
es seguido solo por movimientos ganadores o movimientos perdedores y, por lo tanto, es un movimiento ganador o perdedor.1. d4
con ...resigns
?
Suponga que tiene tres funciones: win_state
, get_player
, y next_states
. La entrada para win_state
es un estado de juego, y la salida es -1 si el blanco está en jaque mate, 0 si es un empate, 1 si el negro está en jaque mate, y de lo None
contrario. La entrada para get_player
es un estado de juego, y la salida es -1 si es el turno de las negras y 1 si es el turno de las blancas. La entrada para next_states
es una lista de posibles estados del próximo juego que pueden resultar de un movimiento legal. Luego, la siguiente función, cuando se le da un estado de juego y un jugador, debería decirle a qué estado de juego debe moverse para que ese jugador gane.
def best_state(game_state,player)
def best_result(game_state):
if win_state(game_state):
return(win_state)
else:
player = get_player(game_state)
return max([best_result(move)*player for move in next_states(game_state)])*player
cur_best_move = next_states(games_state)[0]
cur_best_outcome = -1
for state in next_states(game_state):
if best_result(state)*player > cur_best_outcome:
cur_best_outcome = best_result(state)*player
cur_best_move = state
return(best_move)
Sí. Es fácil. Ni siquiera necesita una potencia de procesamiento infinita. Todo lo que necesitas es una tabla de búsqueda que contenga, para cada posición posible del tablero, el mejor movimiento para jugar en esa posición. Aquí está el pseudocódigo:
def play-move(my-color, board-position):
return table-of-best-moves[my-color, board-position]
El único inconveniente es que esta tabla de consulta tendría que ser muy, muy grande, tal vez más grande que la galaxia de la Vía Láctea, y su construcción tardaría mucho tiempo, tal vez más que la edad actual del universo, a menos que haya cierta regularidad no descubierta en el ajedrez que lo hace mucho más simple de lo que podemos ver en este momento. Pero si tuviera esta tabla de búsqueda, la subrutina para elegir un movimiento perfecto cada vez podría implementarse en tan solo una instrucción de CPU.
Además, dado nuestro conocimiento actual del ajedrez, no hay forma de estar seguros de que el juego perfecto garantiza que no perderá. Por ejemplo, si el juego perfecto garantiza una victoria para las blancas, las negras perderían incluso si las negras juegan perfectamente.