DEV Community

Christian Gonzales Komiya
Christian Gonzales Komiya

Posted on Edited on

[Spanish] Entrenando un kantoku artificial — Capítulo 2: Saihai, el agente que aprendió (y desaprendió) a dirigir

Esta serie tiene tres capítulos:

  1. Por qué no usé una red neuronal: qué es el gateball, qué es un kantoku y cómo pensé el kantoku artificial.
  2. Saihai, el agente : cómo se entrenó, qué aprendió, qué desaprendió y cómo terminó siendo un proyecto propio.
  3. Nana-Ban, el juego: el videojuego donde vive el kantoku, la demo y cómo lo construí con Claude Code.

En el capítulo 1 conté por qué mi kantoku artificial no es una red neuronal, y cómo el primer campeón salió hiperagresivo: atacaba sin parar porque había entrenado contra rivales que nunca atacaban. Ese fue el primer entrenamiento. Este capítulo cuenta todo lo que vino después.

Primero, ¿qué es Saihai?

Saihai (采配) es el nombre del kantoku artificial. En japonés, saihai es la forma de dirigir de un kantoku: sus decisiones tácticas durante el partido.

Técnicamente, Saihai es un agente de IA. Cumple las tres cosas que definen a un agente:

  1. Percibe: lee el estado del partido (dónde está cada bola, a quién le toca, el marcador y el reloj).
  2. Decide: genera decenas de golpes posibles, simula cada uno con la física real del juego (incluido el error del jugador que tira) y evalúa cómo queda la cancha.
  3. Actúa: entrega el tiro (dirección, fuerza y precisión) y el motor lo ejecuta.

Dentro lleva un modelo: los pesos aprendidos por autojuego. Es como un kantoku y su experiencia: el kantoku es el agente; su experiencia es el modelo.

Y una aclaración que hago siempre: no es un modelo de lenguaje ni una red neuronal. Es IA clásica de juegos, de la misma familia que los motores de ajedrez o las IA de billar: búsqueda, simulación y una función de evaluación con parámetros aprendidos, más reglas de experto.

El segundo entrenamiento: menos exposición

Después del campeón hiperagresivo, el objetivo del segundo entrenamiento (el v2) fue que el kantoku dejara de «ofrecerse». Lo había visto en varias partidas: al reentrar a la cancha o al salir de la puerta 1, dejaba su bola justo donde yo podía tocarla.

Cambiamos el entrenamiento por completo. En vez de jugar solo contra los pesos escritos a mano, cada candidato jugaba una liga: contra los pesos a mano, contra el campeón anterior, contra un «salón de la fama» de campeones pasados y contra los otros candidatos. Y le pusimos un piso al riesgo: por más que el optimizador quisiera, exponerse nunca podía valer cero.

Fueron 30 generaciones en 94 minutos. El v2 le ganó el 60 % de los partidos al v1, y las veces que su bola era tocada o sacada al reentrar bajaron del 83 % al 44 %.

Un detalle que me gustó: el peso del riesgo terminó exactamente en el piso que habíamos puesto. Es decir, la máquina no lo descubrió sola: la restricción la pusimos nosotros. Fue la primera señal de algo que se repetiría muchas veces: el criterio humano y el aprendizaje se complementan.

Una bola que se ofreció

Jugando contra el v2 vi una bola de la CPU reentrar y quedar justo al lado de la mía. ¿Por qué, si ahora valoraba el riesgo? Claude Code reprodujo el turno con un script y encontró la causa: el cálculo del riesgo solo miraba a 3 de las 5 rivales. Las que jugaban más tarde no existían para él.

Se corrigió y se continuó el entrenamiento desde donde había quedado, 20 generaciones más. Esa versión le ganó el 69 % al v2.

El efecto techo: cuando ya no se ve la mejora

Después agregué reglas que conozco como jugador: aprovechar la línea de la cancha, cuándo juntarse con una compañera, cómo recoger bolas. Las medí y el resultado fue desconcertante: 51 %, un empate técnico contra el campeón sin esas reglas.

¿No servían? Sí servían, pero no se notaba. El campeón ya les ganaba casi el 98 % de los partidos a los pesos escritos a mano, y al primer rival «tipo humano» que probamos, el 99 %. Cuando ganas casi todo, no queda margen para mostrar que mejoraste. Es el efecto techo: como medir la altura de alguien en una habitación de techo bajo.

La solución fue construir un rival tipo humano cada vez más exigente: una CPU con el error de un buen jugador de gateball (mi referencia: la mitad de los touches a 6 m, uno de cada cinco a 13 m) y que se pasa de fuerza como lo hace una persona. Desde entonces, cada versión se mide también contra ese rival.

El tercer entrenamiento: la máquina tenía razón

Con el v3 pasó algo curioso. El criterio que yo había puesto para adoptarlo decía que el kantoku tenía que pasar la puerta 1 en su primer intento casi siempre. El v3 no lo cumplía: a veces se quedaba esperando en la salida.

Iba a descartarlo, hasta que me di cuenta de que esperar en la salida es una táctica real del gateball: si la cancha está vacía, a veces conviene no entrar todavía. La máquina había descubierto sola una táctica que yo conozco como jugador, y mi criterio de evaluación estaba mal planteado.

Cambiamos el criterio a «espera con sentido» y el v3 pasó a ser el campeón.

La lección: antes de culpar al modelo, revisa la pregunta que le estás haciendo.

El entrenamiento que aprendió a no atacar

El cuarto entrenamiento (le llamamos F) fue el más ambicioso hasta ese momento: unas cinco horas, nueve parámetros nuevos de reglas que yo había agregado jugando, y el rival tipo humano dentro de la evaluación.

El resultado parecía excelente: el candidato le ganaba el 67 % al campeón. Pero una prueba de comportamiento encendió la alarma. En una situación muy clara del gateball (pasas la puerta, ganas un golpe extra y tienes una rival cerca), un kantoku ataca. El candidato no atacaba nunca: 0 de 60 veces.

Había aprendido que podía ganar igual sin atacar en esa situación, así que simplemente dejó de hacerlo. Como estrategia contra las CPU funcionaba; como kantoku, era absurdo.

Lo descartamos y de ahí salió una regla de diseño que sigo usando: lo que un kantoku nunca debe dejar de hacer se programa como regla fija, no como algo que se aprende. El optimizador aprende cuánto vale cada cosa; las convicciones del kantoku no se negocian.

El v4: aprender con examen incluido

Para el siguiente entrenamiento (el v4) cambiamos la forma de evaluar. Además de ganar partidos, cada candidato tenía que rendir una batería de comportamiento: tableros reales de mis partidas, donde se sabe qué haría un kantoku. Así, ganar haciendo absurdos ya no daba puntos.

Fueron 24 generaciones y unas cinco horas. El v4 aprendió algo interesante: cuando va perdiendo, los puntos pesan más. Pero no aprendió que el reloj importa: ese parámetro quedó en cero.

Según el criterio de adopción que habíamos escrito antes de entrenar, el v4 no alcanzaba: tenía que ganarle al menos el 57 % al campeón y llegó al 55,5 %. Contra el rival tipo humano ganaba el 80,5 %, frente al 81,8 % del v3. Pero esas diferencias estaban dentro del ruido de la medición. Lo adopté igual, porque era el primero entrenado con las pruebas de comportamiento dentro de la evaluación, y eso valía más que un punto que podía ser azar.

Desde entonces, Saihai no se ha vuelto a entrenar. Todo lo que mejoró después fueron reglas.

De la máquina al criterio: cinco versiones en un día

El 27 de octubre jugué varias partidas contra el v4 y anoté turno por turno lo que un kantoku habría hecho distinto. Cada observación se convirtió en una regla, y ese día salieron cinco versiones, de la v1.0 a la v1.4.

Versión Qué aprendió (en simple) De dónde salió
v1.0 Calcula cuántos turnos le quedan a cada bola según cómo está la cancha, y valora mejor el doble ángulo «bola y puerta» El parámetro del reloj que el v4 no aprendió
v1.1 Reentradas más cuidadosas: prevé que la rival toque a su compañera y la mande junto a su bola Siete reentradas de una misma partida mía
v1.2 «Casi siempre se reentra»: quedarse fuera bajó del 10,7 % al 0,4 % Mi criterio de kantoku
v1.3 En el último turno busca la cadena de golpes que suma más puntos Un último turno donde solo pasó una puerta
v1.4 El spark ya no saca bolas propias; no arriesga quedar junto a una rival por avanzar si probablemente no vuelve a jugar Un spark que sacó a su propia compañera
v1.5 Con el partido ya ganado, la última bola intenta el touch lejano para sumar Una última bola que no intentó nada

Lo honesto: casi ninguna de estas versiones ganó más que la anterior. Corregían el caso que yo había visto, sin empeorar nada. Para mí eso era suficiente, porque el objetivo no era un kantoku más fuerte, sino uno más parecido a un kantoku real.

Y hubo una idea que descarté a propósito: entrenar a Saihai para imitar mis partidas. Cada kantoku tiene su forma de dirigir, y no quería una copia de la mía. Prefiero que descubra su propio estilo a partir de principios, y que yo le corrija los errores de criterio.

Lo que Saihai todavía no entiende

No todas mis observaciones se pudieron resolver, y creo que esa parte es la más interesante.

El puente que no quiso hacer. En un turno, yo habría puesto la bola 2 junto a la 4 para hacerle de puente (tsunagi): facilitar que la 4 pasara su puerta, en un lugar donde la rival que juega antes no tuviera doble ángulo. Saihai la mandó a un sitio tapado. ¿Por qué? Porque veía tres rivales a 13 metros, cada una con un 20 % de acertar, y sumadas le parecían un peligro serio. Para mí, como kantoku, un touch a 13 metros es muy difícil y no condiciona la jugada.

Probamos varias correcciones y ninguna lo resolvió sin trampas. La diferencia de fondo es cuánto pesa una amenaza lejana, y eso no se debe ajustar a mano para que pase una prueba: se va a calibrar con datos de partidas reales en el próximo entrenamiento.

El peor riesgo tapa a los demás. En otra partida, una bola blanca quedó frente a la puerta 2 con un triple ángulo para una rival. Saihai calcula el riesgo de cada rival como su peor amenaza, no como la suma de todas. Como esa rival tenía una amenaza aún mayor en otro lado, mover la bola «no cambiaba nada» para él. Arreglarlo exige reentrenar, porque los pesos aprendieron con esa forma de medir.

El tiro que no existía. Otra vez yo habría dejado la bola pegada a la línea para dominar la zona de la puerta 2. Saihai midió que tenía razón: ahí era más segura. Pero desde donde estaba, los postes de la puerta tapaban ese tiro. No era un error de criterio, sino de opciones.

Todo esto está documentado para la próxima versión grande, la v2.0.

Medir sin engañarse

Si algo aprendí en este proyecto es a desconfiar de los números bonitos.

Con 200 partidos, cada cifra tiene un margen de ±5 a 7 puntos. Una vez, un candidato parecía ganar el 63,5 %, y al medirlo bien bajó a 60 %: era el mejor de 11 mediciones con ruido. Otra vez, un 81,5 % no se pudo reproducir: dio 76,8 %.

La lección más clara llegó con la última versión. Comparé la v1.5 contra la v1.4 y dio 47,8 %, por debajo del 48 % que había puesto como meta. Antes de concluir que era peor, medimos un control: la v1.4 contra sí misma, con las mismas semillas. Dio exactamente 47,8 %. La meta era imposible incluso para dos copias idénticas.

El gráfico mezcla condiciones distintas (certeza, rivales y hasta el grosor del poste), así que no es una serie continua. Lo que muestra es otra cosa: cuánto se mueven los números por razones que no son «mejorar».

De parte del juego a proyecto propio

Al principio, el kantoku vivía dentro del juego. Pero un kantoku artificial de gateball podía servirle a otros: a quien quiera hacer su propio juego de gateball, en otro motor o con otra estética. Así que decidí separarlo en su propio repositorio, sin interfaz, como una librería.

El kantoku «piensa» simulando tiros con las reglas y la física, así que no se podía ir solo: se llevó también el motor de gateball. Hoy el juego usa ese mismo paquete para las reglas y para la IA. Una sola fuente de verdad.

La condición que puse fue estricta: después de separarlo, tenía que jugar idéntico. No «parecido»: idéntico. Se midió todo antes y después con las mismas semillas, y los resultados coincidieron partido por partido, hasta los archivos de referencia byte a byte.

Esa comparación encontró algo que nadie había visto: algunas pruebas leían partidas guardadas solo en mi laptop. En una copia limpia del repositorio, esas pruebas veían la mitad de los datos y pasaban igual, sin avisar. Las 23 partidas quedaron versionadas como parte de las pruebas.

Usar Saihai se ve así:

import { createMatch, Saihai, playShot } from 'saihai-gateball';

const match = createMatch({ seed: 42 });            // partido con azar reproducible
const saihai = new Saihai({ opponent: 'human' });   // juzga a su rival como a una persona

while (match.stage !== 'done') {
  const shot = saihai.chooseShot(match);            // Saihai decide el tiro
  const res = playShot(match, shot);                // el motor lo ejecuta
  console.log(res.events);                          // puertas, touches, sparks, faltas…
  match.proceed();                                  // siguiente golpe o turno
}
console.log(match.teamScore(0), match.teamScore(1));
Enter fullscreen mode Exit fullscreen mode

Sin Phaser, sin navegador: corre en Node o en cualquier juego web. La misma semilla reproduce exactamente el mismo partido, y Saihai puede explicar cada decisión, en español o en inglés.

Para comprobar que de verdad servía a otros, hicimos una prueba de «desarrollador externo»: una carpeta vacía, instalar Saihai desde GitHub y jugar un partido usando solo lo que dice el README. Funcionó, y de esa prueba salieron once mejoras a la documentación.

Saihai en Hugging Face

El último paso fue publicarlo donde la comunidad de IA busca modelos y agentes: Hugging Face. Ahí están los pesos (31 valores aprendidos por autojuego y 14 fijos), una ficha que explica qué es y qué no es, y un Space donde cualquiera puede jugar contra Saihai desde el navegador.

Hugging Face no tiene una categoría de «agentes», así que Saihai aparece como modelo. Es lo habitual con los agentes de juegos: el repositorio de modelo guarda lo que el agente aprendió, y el Space lo muestra funcionando.

Las cifras de hoy

Medida Saihai v1.5
Contra la versión anterior (200 partidos) 47,8 %, igual que el control
Contra el rival tipo humano (200 partidos) 84,5 %, con 7 puntos de diferencia por partido
Pruebas de comportamiento (tableros de mis partidas) 98 %
Tiempo para decidir un golpe unos 53 ms en mi laptop
Valores aprendidos 31 (más 14 fijos)

Una advertencia importante: todas son cifras contra rivales simulados. Contra personas reales, por ahora, solo están mis partidas. Y ya me ganó un partido, bien jugado.

Lo que viene

El próximo paso es un nuevo entrenamiento, la v2.0, con una diferencia clave: calibrar el rival humano con mis partidas reales. Mis partidas guardadas registran cada tiro, así que se puede medir cuánto acierto yo de verdad a 6, 9 o 13 metros, en vez de suponerlo. Si a 13 metros acierto menos de lo que Saihai cree, aprenderá solo que esas amenazas pesan poco. Que es justo lo que yo, como kantoku, le habría dicho.

Mientras tanto, sigo jugando y anotando turnos.

Enlaces

Próximo capítulo

En el capítulo 3 hablo del juego donde vive Saihai: Nana-Ban. De qué consta, por qué lo hice con Phaser, cómo es la demo (también en el celular), dónde se puede jugar y cómo lo construí con Claude Code, iteración por iteración.

Top comments (0)