Si solo necesita 3 en una fila, X gana para todos n> 3 donde n es la dimensión del tablero.
Considere un 4 × 4:
Coloque la X en uno de los cuadrados centrales (por simetría, importa cuál elija):
_ _ _ _
- ¿Alguien puede interpretar este gráfico de resultados de una simulación de faro shuffle?
- Cómo resolver una pregunta matemática bajo presión
- ¿Cómo resolvemos los problemas cuando el purificador de aceite centrífugo tiene fiebre?
- ¿Cuál es un ejemplo del uso del método babilónico para encontrar la raíz cuadrada de un número?
- Cómo demostrar que resolver una función es más difícil que otra
_ _ X _
_ _ _ _
_ _ _ _
Tu oponente tiene cuatro opciones (una para cada fila):
_ _ _ _ | _ _ _ _ | _ _ _ _ | _ _ O _ |
_ OX _ | _ _ X _ | _ _ XO | _ _ X _ |
_ _ _ _ | _ _ O _ | _ _ _ _ | _ _ _ _ |
_ _ _ _ | _ _ _ _ | _ _ _ _ | _ _ _ _ |
o O puede jugar en cualquier otra casilla (movimiento A), su respuesta:
_ _ _ _ | _ _ _ _ | _ _ _ _ | _ _ O _ |
_ OX _ | _ XX _ | _ _ XO | _ XX _ |
_ _ X _ | _ _ O _ | _ _ X _ | _ _ _ _ |
_ _ _ _ | _ _ _ _ | _ _ _ _ | _ _ _ _ |
llame a estos movimientos 1, 2, 3, 4, en nuestro último caso donde O jugó en otra casilla (movimiento A):
si O jugó en la 1ra, 3ra o 4ta fila, juega el movimiento 2, de lo contrario juega el movimiento 1.
Puede reducir esto a simplemente:
def playMoveX (tablero, turnNumber, lastPlaced):
# lastPlaced es una tupla (fila, columna)
if turnNumber == 1: # primer turno, sin contar en francés
board.place (“X”, fila = 0, columna = 2) # recuento francés
elif turnNumber == 3:
# si O jugó en la segunda fila (conteo francés)
if lastPlaced [0] == 1:
board.place (“X”, fila = 2, columna = 3) # recuento francés
más:
board.place (“X”, fila = 1, columna = 1) # recuento francés
más: # gana aquí
# TODO: comprueba cuál de los dos cuadrados x tiene libre y gana
Ahora, si pregunta qué sucede cuando necesita k, en una fila, en una placa nxn, n> = k> 3, aquí es donde entra la poda alfa-beta en la parte superior de minimax (como han mencionado otros).
La idea es simple, finge que tu oponente jugaría el movimiento óptimo, si jugó el movimiento óptimo, y tú jugaste de manera óptima, ¿qué jugarías?
def playMove (Xmove, tablero):
score = board.score ()
if board.gameover (): # ya sea sin movimientos o ganador
puntaje de retorno
# no Xmove, porque estamos cambiando de lado
seqOfNextMoves = (playMove (no Xmove, board.pretendPlay (openTile)) para openTile en board.openTiles ())
si Xmove:
return max (seqOfNextMoves)
más:
return min (seqOfNextMoves)
Esto es solo minimax, para la poda alfa-beta, querrás podar este gran árbol (especialmente a medida que n crece). Poda alfa-beta
Editar con poda alfa-beta:
copia de importación
def abPrune (alfa, beta, Xmove, placa):
if board.gameover (): # empate o alguien ganó
return board.score ()
# si es el movimiento de X, entonces queremos maximizar la puntuación, de lo contrario minimizar
# establecemos el valor en un puntaje peor que el puntaje mínimo posible para X, y el puntaje más grande posible para O, ya que
# x quiere maximizar su puntaje, y O quiere minimizar su puntaje (ver board.score ())
func, value = (max, -2) si Xmove else (min, 2)
para emptyTile en board.emptyTiles ():
# llama recursivamente, no Xmove porque estamos cambiando de lado.
# ver qué pasaría si jugamos este movimiento
value = func (value, abPrune (alpha, beta, not Xmove, board.pretendPlay (emptyTile, Xmove)))
alpha = func (alpha, value) # min o max dependiendo de quién es el turno
si beta <= alfa: # si baja por este camino dará lugar a una peor puntuación posible
rotura
valor de retorno
Tablero de clase ():
def __init __ (self, filas, columnas, cantidadNeededToWin = 3, emptyTileStr = “_”):
self.amountNeededToWin = cantidadNeededToWin
self.emptyTileStr = emptyTileStr
self.board = [[emptyTileStr para r en rango (filas)] para c en rango (columnas)]
def place (self, position, Xmove):
fila, columna = posición
tile = “X” si Xmove más “O”
self.board [fila] [columna] = mosaico
def pretendPlay (self, position, Xmove):
temp = copy.copy (tablero)
lugar temp. (posición, Xmove)
temperatura de retorno
def emptyTiles (self):
para i, rowArray en enumerate (self.board):
para j, val en enumerate (self.board [i]):
si val == self.emptyTileStr:
rendimiento (i, j)
def xwin (auto):
# Cosas TODO aquí
…
def owin (auto):
# Cosas TODO aquí
…
def tie (self):
# Cosas TODO aquí
…
puntaje de def (auto):
si self.xwin ():
volver 1
elif self.owin ():
volver -1
elif self.tie ():
volver 0
más:
# Cosas TODO aquí
… # Número de retorno x, -1 <x <1
… # debe evaluar qué jugador está en una mejor posición
def gameover (auto):
si self.xwin () o self.owin () o self.tie ():
volver verdadero
falso retorno
filas, columnas = 5,5
abPrune (-2, 2, True, Board (filas, columnas, cantidadNeededToWin = 3))