🤖 Игра нашего движка против сайт-ботов

Идея: запускать наш Scala-движок против сайт-ботов dicechess.com (DC Coach Beginner / Amateur / Master) — это объективный бенчмарк силы движка (качество эвристик и поиска на разных уровнях). Партии можно писать в SQLite dicechess-lab для аналитики (винрейт, среднее время хода, распределение бросков). Реализация — dicechess-bots.

Архитектурное решение: Scala.js в Node, без IPC

Рассматривали два подхода связать движок с сайтом:

Python-мост + субпроцесс движкаNode + Scala.js-движок (выбрано)
Связь с движкомотдельный процесс Scala, обработка stdin/stdout или HTTPдвижок скомпилирован в JS (Scala.js) → импортируется как модуль, вызовы в памяти
Накладные расходымежпроцессные вызовы (IPC)нет IPC
Идентичность средыдругая среда, чем браузеркак в браузере PWA-тренажёра
STOMPstomp.py@stomp/stompjs + ws

Раз движок и так собирается в JS (Scala.js), Node-раннер просто импортирует engine.js и вызывает поиск хода напрямую — это проще и элегантнее моста на Python.

Куда положить раннер

Решение: держать раннер рядом с движком — в dicechess-engine-scala (scripts/) или в выделенном dicechess-bots, который линкует движок локально (file:../dicechess-engine-scala). Отдельный «третий» репозиторий без локального линка добавил бы боль синхронизации: каждое изменение Scala → пересборка JS → публикация/npm link → обновление зависимости у ботов — медленный feedback loop. Локальный линк (как в dicechess-bots) убирает этот шаг.

Схема работы раннера:

sequenceDiagram
    participant S as 🌐 dicechess.com (STOMP)
    participant R as 🤖 Node-раннер
    participant E as ♟️ Scala.js-движок (в памяти)
    S-->>R: бросок кубиков + FEN
    R->>E: getBestMove(DFEN, algorithm)
    E-->>R: лучший ход (UCI)
    R->>S: MOVE

Связанное