gambit

Un motor de ajedrez en Scala 3. Generación de jugadas, evaluación de posiciones y búsqueda - un cerebro completo para jugar al ajedrez, construido con scala-cli.

gambit
TL;DR

Un motor de ajedrez en Scala 3. Tres cosas difíciles a la vez: una generación de jugadas impecable, una evaluación de posición con sentido y una búsqueda que elige una buena jugada en un tiempo razonable. Un cerebro completo para jugar.

Introducción

Un motor de ajedrez solo parece un proyecto. Son tres subsistemas, cada uno capaz de arruinar el conjunto a su manera, y solo juntos producen algo que juega con sentido. gambit consiste en hacer que esas tres partes concuerden lo bastante bien como para que el resultado empiece a parecerse a un rival de verdad, y no a un generador de jugadas al azar.

Scala 3 ofrece aquí un lenguaje expresivo para modelar el tablero, las jugadas y el árbol de variantes. Pero el verdadero reto no es sintáctico, es algorítmico: un generador impecable, una evaluación justa y una búsqueda que no calcule sin fin.

Tres problemas que deben concordar

Un generador de jugadas que deja pasar una jugada ilegal por cada millón de posiciones hará que el motor juegue algo imposible. Una evaluación que pesa mal las piezas lo llevará a una derrota con convicción. Una búsqueda sin poda pensará durante horas en una jugada que debería caer en un segundo.

1
Generación de jugadas

todas las jugadas legales en cualquier posición, incluido el enroque, la captura al paso y la promoción.

2
Evaluación de posición

un número que expresa quién está mejor mientras la partida sigue en curso.

3
Búsqueda

alfa-beta, que descarta las ramas que no vale la pena calcular.

Ninguno de estos tres se puede descartar. Un motor débil en cualquiera de ellos perderá, y por un motivo concreto y señalable, no por una debilidad general.

Alfa-beta, el arte de no calcular

La búsqueda ingenua examina cada continuación posible, y hay miles de millones ya a pocas jugadas de profundidad. La poda alfa-beta advierte que si una respuesta del rival ya refuta una línea, no hace falta calcular el resto de sus respuestas. Con un buen orden de jugadas, esto corta el espacio con tanta fuerza que el motor llega más hondo en el mismo tiempo.

Nodos a explorar a la misma profundidad (orientativo, miles)

Búsqueda ingenua
1000
Con poda alfa-beta
60

No es una optimización menor sino la diferencia entre un motor que ve tres jugadas por delante y uno que ve seis. En ajedrez esa profundidad se traduce directamente en fuerza de juego.

Perft, la prueba de la corrección del generador

La corrección del generador de jugadas se verifica con el llamado perft: cuentas todas las posiciones alcanzables a una profundidad dada y las comparas con números que toda la comunidad ajedrecística sabe de memoria. Si tu número no cuadra, tienes un bug en algún sitio, y se ve exactamente a qué profundidad empieza la divergencia.

Perft desde la posición inicial

ProfundidadNúmero de posiciones
120
2400
38902
4197281
54865609

El resultado es un motor completo que toma una posición y devuelve una jugada: el generador expone todas las continuaciones legales, la evaluación dice cuál lleva hacia un lado mejor, y alfa-beta busca tan hondo como el tiempo permite. Tres subsistemas que por separado son solo partes, juntos forman un rival que sabe jugar.

➜
Consejo

El perft es el ejemplo de manual de una prueba que puede fallar de verdad. No comprueba que algo funcione, compara tu número con un número conocido de antemano, así que cualquier bug en el generador desvía el resultado al instante.

Más proyectos

Más trabajos de la misma categoría - mira cómo abordamos retos parecidos.

¿Tiene un proyecto similar?

Escríbenos - el presupuesto es gratuito y llega en una hora.