Perder en tres en raya

18

Escribe un programa que juegue un juego de Misère tic-tac-toe. Es decir, el objetivo es obligar a tu oponente a tomar tres seguidos.

Acepte en la entrada estándar una 'X' o una 'O' (la letra, no cero), para determinar de qué lado se reproducirá el programa. Luego saca un solo dígito para tu movimiento en tu turno y lee un solo dígito en el turno de tus oponentes hasta que termine el juego (X siempre va primero). Una vez que se decide un ganador, genera X u O para quién ganó, o D para un empate. Por ejemplo, si O obtiene 3 seguidos, X gana.

Suponga que el tablero está numerado así:

0|1|2
-----
3|4|5
-----
6|7|8

Idealmente, una solución será óptima y nunca perderá. Al igual que el tic-tac-toe, el juego perfecto siempre debe resultar en un empate. Si se cumple el protocolo anterior, puedo probar los envíos automáticamente contra una variedad de posibles estrategias.

El ganador es el código más corto. puntos de bonificación si elige al azar de movimientos igualmente buenos para hacerlo un poco más impredecible.

captncraig
fuente

Respuestas:

10

Python, 383 caracteres

M=[21,1344,86016,4161,16644,66576,65793,4368]
X=lambda B,k:any(m*k==B&m*3for m in M)
def S(B):
 if X(B,2):return 1,
 M=[i for i in range(0,18,2)if B>>i&3<2]
 return max((-S((B|3<<i)^87381)[0],i)for i in M)if M else(0,)
r='D'
c=ord(raw_input())&1
B=0
for i in range(9):
 if i&1==c:m=S(B^c*87381)[1];print m/2;B|=3-c<<m
 else:
  B|=2+c<<input()*2
  if X(B,2+c):r='XO'[c];break
print r

El tablero Bse representa como un entero usando dos bits por cuadrado, con 00y 01representando vacío, 10representando O y 11representando X. Mes un conjunto de máscaras de bits con 01los puntos de un triple perdedor ( 21= 0b010101= la fila superior, etc.) Xcalcula si alguno pierde triple para kestá presente en un tablero. Sminimax busca un movimiento óptimo para X, devolviendo un par de puntaje (1 = ganar, -1 = perder, 0 = empatar) y un índice cuadrado. ^87381(= ^0b010101010101010101) voltea X y O mientras deja cuadrados vacíos sin cambios.

La computadora nunca pierde, así que no necesité incluir ese cheque :).

Probablemente exista un algoritmo más fácil / más corto basado en reglas, pero esto funciona.

Keith Randall
fuente
Sneaky sneaky bitwise brujería +1
Rohan Jhunjhunwala