La forma ganadora

○_○○○, con una casilla vacía en medio, se convierte en cinco en cuanto se rellena esa casilla. En la terminología del gomoku, esto es un cuatro partido. Si con una sola jugada se forma este cuatro partido junto con un tres seguido (○○○) en otra línea, se gana. El rival tiene que bloquear primero el cuatro, y mientras tanto el tres se convierte en un cuatro abierto, que ya no se puede detener. Esto es un cuatro-tres.

Las personas encuentran esta posición con facilidad. Pero la IA actual no la juega aunque pueda formar esta figura con sus propias piedras.

Un cuatro-tres que la IA pasó por alto. Jugando en la posición punteada se forman un cuatro partido horizontal y un tres seguido vertical, pero la IA jugó en el extremo izquierdo de la línea
Un cuatro-tres que la IA pasó por alto. Jugando en la posición punteada se forman un cuatro partido horizontal y un tres seguido vertical, pero la IA jugó en el extremo izquierdo de la línea

En partidas reales

Volví a reproducir 24 partidas web y busqué los momentos en los que la IA (blancas) podía formar un cuatro-tres con una sola jugada. Hubo 7 momentos así, y la IA solo jugó en esa posición una vez. Desaprovechó las 2 ocasiones en las que podía ganar con un cuatro partido.

Las personas, en cambio, ganaron con esa misma forma. De las 22 partidas que ganaron las personas, 11 terminaron con un cuatro-tres.

Cómo terminaron las 22 partidas que ganaron las personas. Cuatro abierto 9, cuatro-tres (tres seguido) 6, cuatro-tres (tres partido) 5, cuatro-cuatro 2
Cómo terminaron las 22 partidas que ganaron las personas. Cuatro abierto 9, cuatro-tres (tres seguido) 6, cuatro-tres (tres partido) 5, cuatro-cuatro 2

Abajo está una de esas partidas. Cuando negras jugaron en la posición punteada, aparecieron a la vez un cuatro partido en diagonal (●●_●●) y un tres partido en horizontal (●●_●).

Un cuatro-tres en una partida real. Con la jugada 23 de negras aparecen a la vez un cuatro y un tres partido
Un cuatro-tres en una partida real. Con la jugada 23 de negras aparecen a la vez un cuatro y un tres partido

Prueba de la IA local

Trasladé tal cual el código de la IA local de la web y lo probé en un tablero de 15×15, cambiando la orientación al azar. Encontró su propia posición de cuatro-tres en un 29% de los casos con un cuatro seguido (○○○○) más un tres, y en un 27% con un cuatro partido (○_○○○) más un tres. También bloqueó de antemano la posición en la que el rival podía formar un cuatro-tres en la siguiente jugada solo un 33% de las veces. Bloquear un solo tres funcionó en un 67% de los casos con un tres seguido y en un 100% con un tres partido.

Prueba de la IA local. Encontrar mi cuatro-tres: cuatro seguido 29%, cuatro partido 27%; bloquear la posición de cuatro-tres del rival 33%; bloquear un tres seguido 67%; bloquear un tres partido 100%
Prueba de la IA local. Encontrar mi cuatro-tres: cuatro seguido 29%, cuatro partido 27%; bloquear la posición de cuatro-tres del rival 33%; bloquear un tres seguido 67%; bloquear un tres partido 100%

Por qué no lo ve

La IA local puntúa cada casilla vacía por separado en cuatro direcciones y suma los resultados. Pero en cada dirección cuenta cinco casillas solo hacia delante desde esa casilla, por ejemplo hacia la derecha o hacia abajo, y no mira hacia atrás. Si las piedras del cuatro y del tres están a la izquierda y por encima de la posición de cuatro-tres, como en la imagen de arriba, desde esa posición no se ve ni una sola piedra. En cambio, mirando hacia la derecha desde el extremo izquierdo de la línea se ven tres piedras, así que elige esa posición.

Además, se limita a sumar la puntuación de cada línea y no comprueba por separado que dos líneas se crucen en un punto para formar un cuatro-tres. El código que busca jugadas ganadoras solo comprueba las jugadas que forman cinco de inmediato. Por eso solo juega un cuatro-tres cuando la dirección coincide por casualidad.

La comprobación de jugadas prohibidas la hace el motor por separado, y el motor detecta correctamente como prohibido el doble tres que incluye un tres partido. Las reglas se están viendo bien; lo que falla es el criterio de quien juega.

El código real de este paso

Esta es la parte en la que la IA local puntúa una casilla vacía. Se puede ver que solo cuenta las cinco casillas de delante.

omook-web/lib/ai.tstypescript · 38 líneas
function linePotential(
  board: Stone[],
  r: number,
  c: number,
  dr: number,
  dc: number,
  color: Stone,
  size: number,
): number {
  let streak = 0;
  let blockedNear = false;
  const rr0 = r - dr;
  const cc0 = c - dc;
  if (inBounds(rr0, cc0, size)) {
    const oc = board[idx(rr0, cc0, size)];
    if (oc !== EMPTY && oc !== color) blockedNear = true;
  }

  let rr = r;
  let cc = c;
  for (let k = 0; k < 5 && inBounds(rr, cc, size); k++, rr += dr, cc += dc) {
    const v = board[idx(rr, cc, size)];
    if (v === color) streak++;
    else if (v === EMPTY) {
      /* open */
    } else break;
  }
  let score = streak * streak * 120;
  if (streak >= 4) score += 50000;
  if (blockedNear && streak >= 4) score = Math.floor(score / 8);
  return score;
}

function scorePlacement(board: Stone[], r: number, c: number, who: Stone, size: number): number {
  let s = 0;
  for (const [dr, dc] of DIRS) s += linePotential(board, r, c, dr, dc, who, size);
  return s;
}

La siguiente entrada es "4. Un plan para que el VLM aprenda la heurística y la heurística vuelva a ser la profesora".