lighthouses-bot
- rust
- python
- heuristics
- game-bot
Mi bot ganaba casi todas las partidas. El problema es contra quién las jugaba.
Para un concurso monté en Rust un bot para un juego de control de territorio, y lo hice pasar por ocho generaciones. El recorrido dio una lección buena sobre la complejidad: probé lo vistoso —búsqueda en árbol tipo MCTS, aprendizaje por refuerzo, Thompson Sampling para elegir estrategia— y casi nada sobrevivió. Ganaba la heurística explícita, la que decide en menos de un milisegundo. El momento más claro fue una versión que reescribí para ser más sofisticada, con más capas y más matices: ganaba el 34% de las partidas, y la anterior, más simple, ganaba el 53%. Revertí el cambio y me quedé con que la complejidad añade modos de fallo más rápido de lo que añade valor. La otra lección de esa época no fue sobre IA sino sobre leer: el reglamento decía una cosa y el motor del juego hacía otra, y varias ventajas salieron de leerme el código en vez de la documentación.
Luego lo medí contra bots reales, de otros competidores, sacados de GitHub. Cuarto de cinco, y el de cabeza le sacaba cuatro veces la puntuación. Las ocho generaciones habían estado compitiendo entre ellas todo el tiempo, y yo había confundido ese ranking con una medida de calidad.
Así que tiré el bot y empecé otro de cero en Python, esta vez contra el campo real desde el primer día. Al día siguiente ya iba primero de siete, por delante de los que me habían ganado. Un par de días después congelé la versión y la di por buena. No me aguanté mucho: dos días más tarde le añadí un ajuste que rendía un 6,8% más, con la significancia estadística en la mano.
Una semana más tarde apareció el paquete del organizador con las condiciones reales del torneo. Se jugaba a 1.200 rondas y con hasta dieciséis jugadores; yo lo había medido todo con trescientas rondas y siete. El mapa que usaba de referencia lo había reconstruido a ojo. Y aquel ajuste del 6,8%, el último que había metido, resultó hacer un 24% de daño en uno de los mapas oficiales. Dejé de aplicarlo en todas partes y lo pasé a una tabla por mapa: activo solo donde estaba medido que no hacía daño, y desactivado en cualquier mapa que no conociera.
Quedé cuarto. La lección que me llevo no va de bots: el alcance de lo que mides es el alcance de lo que puedes concluir, y ni un decimal más. Tenía cientos de partidas de respaldo y aun así no estaba midiendo lo que creía, dos veces seguidas y por motivos distintos.
Cómo está hecho — Rust y Python · heurísticas explícitas · sin modelos entrenados