Skip to content

Latest commit

 

History

6 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Крестики-нолики · 5 в ряд

Гомоку против сильного движка, на тетрадном листе или на школьной доске. Ходы — крестики и нолики в клетках, а не камни на пересечениях.

Весь расчёт идёт в браузере. Сервер отдаёт только статические файлы: ни ходы, ни партии никуда не уходят.

Что внутри

Движок Rapfi 0.43.01, WebAssembly, один поток + SIMD128
Оценка NNUE mix9svq, сеть freestyle для всех размеров поля
Правила freestyle: пять и больше в ряд, запрещённых ходов нет
Поле 13×13, 15×15, 19×19
Вес ~9,6 МБ пакета весов + 1,1 МБ .wasm, качается один раз
Языки русский, English, қазақша, Deutsch, español, français, Türkçe, فارسی (RTL), 中文
PWA ставится на домашний экран, играет полностью офлайн

На обычном ноутбуке движок успевает просчитать 18–25 полуходов за пару секунд в одном потоке. Многопоточная сборка требует заголовков COOP/COEP и SharedArrayBuffer, которых статический хостинг не даёт — да и одного ядра здесь с запасом.

Как это устроено

docs/
  index.html          интерфейс
  about.html          страница «о движке»
  assets/app.js       отрисовка поля, правила, связка с движком
  assets/i18n.js      словари девяти языков и переключатель
  assets/style.css    две темы: тетрадь и доска
  assets/pwa.js       регистрация сервис-воркера
  sw.js               офлайн-кэш: оболочка, движок и шрифты порознь
  manifest.webmanifest
  icon-*.png          иконки приложения, рисуются кодом
  engine/worker.js    обёртка над wasm: движок считает в воркере
  engine/rapfi-*.js   загрузчики emscripten (SIMD и запасной без SIMD)
  engine/rapfi-*.wasm бинарники Rapfi
  engine/rapfi.data   веса и конфиг
tools/repack-engine.js  пересборка пакета весов с 40 МБ до 9,6 МБ
tools/make-icons.js     генерация иконок PWA
serve.js                локальный сервер для разработки

Язык определяется по navigator.languages, запоминается в localStorage и переключается в шапке. Разметка помечена атрибутами data-i18n; числа форматирует Intl.NumberFormat с компактной записью, поэтому «53,4 тыс.», «53.4K» и «5.3万» получаются сами собой.

Персидский идёт справа налево: dir="rtl" переворачивает раскладку логическими свойствами CSS, а поля тетрадного листа с красной чертой переезжают на правый край. Caveat не знает арабицу, поэтому для фарси подгружается Vazirmatn — только при выборе этого языка, остальные за него не платят.

Офлайн и установка

Сайт — прогрессивное веб-приложение: ставится на домашний экран и после первого запуска работает без сети совсем. Это естественно ложится на архитектуру — считает движок и так на устройстве, сервер нужен ровно один раз.

Кэша в sw.js три, и это принципиально:

Кэш Что в нём Когда наполняется
xo5-shell HTML, CSS, JS, иконки, манифест — около 130 КБ при установке воркера
xo5-engine rapfi.data, .wasm, загрузчик — 11 МБ лениво, когда страница сама их запросит
xo5-fonts Caveat и Vazirmatn с Google Fonts при первом обращении

Движок нельзя класть в предзагрузку: воркер начал бы качать те же 11 МБ параллельно со страницей, и первый визит стоил бы 22 МБ вместо 11.

Стратегии: переходы по страницам — сеть вперёд с откатом в кэш, свои файлы — отдаём из кэша и молча освежаем, файлы движка и шрифты — только кэш, они неизменяемы. Поэтому правки интерфейса доезжают до пользователя со второй загрузки сами; принудительно сбросить кэш можно, подняв SHELL_CACHE в sw.js. Версию ENGINE_CACHE трогать нужно, только если пересобран пакет весов.

Иконки рисует tools/make-icons.js: PNG кодируется вручную через zlib, сглаживание — суперсэмплингом. Так палитра гарантированно совпадает с тёмной темой сайта, а внешних зависимостей у проекта по-прежнему нет.

node tools/make-icons.js

Движок общается по протоколу Piskvork с расширениями Yixin-Board. Перед каждым ходом ему отправляется полная позиция командой BOARD … DONE, поэтому отмена ходов и смена настроек не могут рассинхронизировать состояние.

Поиск в однопоточной сборке блокирует свой поток целиком, поэтому движок живёт в Web Worker — интерфейс остаётся отзывчивым, а промежуточные INFO долетают до панели анализа прямо во время счёта.

Локальный запуск

node serve.js

Затем открыть http://localhost:5173.

Пересборка пакета движка

Оригинальный веб-пакет Rapfi весит ~40 МБ: в нём четыре NNUE-сети — freestyle, standard и две рэндзю. Здесь нужна только freestyle:

node tools/repack-engine.js

Скрипт качает файлы с gomocalc.com, режет rapfi.data по таблице смещений, оставляет одну сеть, правит config.toml и переписывает таблицу в загрузчиках. .wasm не трогается вообще.

Лицензии

Движок Rapfi — GPL-3.0, автор dhbloo и участники проекта. Исходники: https://github.com/dhbloo/rapfi.

Файлы в docs/engine/ — это сборка Rapfi для WebAssembly, взятая из веб-версии Gomocalc того же автора. .wasm распространяются без изменений; изменены только состав пакета весов и config.toml, ровно так, как это делает tools/repack-engine.js. Условия GPL-3.0 распространяются на эти файлы и на любую их дальнейшую передачу.

Интерфейс (docs/index.html, docs/about.html, docs/assets/*, docs/engine/worker.js, tools/*, serve.js) — MIT.

About

Гомоку (5 в ряд) против движка Rapfi. Всё считается в браузере через WebAssembly. Тетрадь в клетку или мел на доске.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages