Jaque: un motor de ajedrez construido desde cero en Rust
Sin frameworks de ajedrez y sin nube: un programa que calcula sus jugadas dentro de tu navegador gracias a WebAssembly. Tu CPU es su cerebro; no hay servidores ni cuentas.
Jugar contra Jaque¿Cómo piensa un motor?
Un motor de ajedrez no «sabe» ajedrez como un humano: hace tres cosas muy simples, millones de veces y muy deprisa.
Evaluar
Ante cada posición, Jaque la puntúa: material, actividad de las piezas, estructura de peones, seguridad del rey… Decenas de pesos que deciden qué le gusta y qué no.
Buscar
Explora un árbol de variantes: «si yo juego esto y tú aquello…». La poda alpha-beta descarta pronto las ramas malas, y eso le permite mirar cientos de miles de posiciones por segundo en tu pestaña.
Decidir
El reloj manda. Jaque reparte su tiempo: piensa más cuando la posición es crítica y mueve rápido cuando su mejor jugada lleva rato siendo estable.
La historia: de mover piezas a +900 Elo
Jaque se construyó por fases, y cada mejora tuvo que ganarse su sitio: solo se acepta si vence a la versión anterior en un match estadístico (SPRT) — cientos de partidas hasta que los números dicen si de verdad es mejor. Eso también significó tirar trabajo a la basura. Dos veces.
Fase 1
Un motor que juega — y una arena para verlo
Lo primero: hablar UCI (el idioma estándar de los motores), generar solo jugadas legales y buscar con alpha-beta básico. De regalo, una arena de terminal para verlo jugar contra sí mismo en directo.
Fase 2
Ojos y memoria
Evaluación PeSTO (tablas pieza-casilla usadas por motores serios) y una tabla de transposición: memoria para no recalcular posiciones que ya visitó por otro orden de jugadas.
Fase 3+373 Elo
Podar mejor y administrar el reloj
Poda de jugada nula, reducciones en jugadas tardías, búsqueda de capturas con SEE y una gestión de tiempo que piensa más en los momentos críticos. El mayor salto de fuerza de todo el proyecto.
Fase 4
Una evaluación con criterio
Estructura de peones, movilidad, par de alfiles, torres en columnas abiertas, seguridad del rey… Cada término tuvo que ganarse su sitio en un mini-match de validación.
✗ Primer intento de afinar los pesos automáticamente (tuning Texel con 28.000 posiciones propias): −80 Elo. Revertido.
Fase 5+50 Elo
Búsqueda II
Podas más finas moduladas por si la posición mejora o empeora, y una tabla de transposición reescrita con generaciones. Verificado por SPRT: +50 Elo [+26, +75].
Fase 6
Detalles de maestro
Peones pasados protegidos, caballos en outpost, los reyes en los finales, presión de piezas sobre el rey rival — los matices que distinguen a un motor de club de uno serio.
✗ Segundo intento de tuning, esta vez con 2,4 millones de posiciones de partidas reales: tampoco mejoró (−10 Elo, empate estadístico). Revertido otra vez. Moraleja: medir gana a intuir.
¿Cómo de fuerte es?
Para medirlo, Jaque jugó un gauntlet contra Stockfish con la fuerza limitada a distintos niveles, anclando su rating al de su rival: ≈2875 Elo (intervalo del 95%: [2765, 2983]) en la escala UCI_Elo.
Letra pequeña, porque la honestidad también se mide: la escala UCI_Elo de Stockfish corre alta — en la lista CCRL Jaque rondaría los 2400-2600; en el navegador (WebAssembly) rinde algo menos que en nativo; y los niveles Fácil, Medio y Difícil juegan aposta más flojo para que la partida sea justa.
Lo que viene
Hoja de ruta aspiracional, sin fechas ni promesas:
NNUE
Sustituir la evaluación artesanal por una pequeña red neuronal entrenada con millones de posiciones — el salto que dispara a los motores modernos.
Finales perfectos
Tablas de finales Syzygy: con pocas piezas en el tablero, jugar perfecto por lectura directa en vez de calcular.
Búsqueda paralela
Lazy SMP: buscar con varios hilos a la vez, escalando con los núcleos de tu máquina.
Bot en Lichess
Conectar a Jaque a lichess.org para que cualquiera pueda retarlo desde su cuenta, con relojes y ranking de verdad.
Bajo el capó
El motor está escrito en Rust y compilado a WebAssembly; corre en un Web Worker para no congelar la página, y chess.js arbitra las reglas en la interfaz. La web es estática: no hay backend, el rival vive en tu CPU. Construido por Víctor con ayuda de Claude.