Files
Ustagammon/docs/adr/0005-moteur-gnubg-officiel.md

6.0 KiB

0005. Source du moteur : GNU Backgammon officiel, commit 14b6798

  • Statut : accepté
  • Date : 2026-11-02
  • Décideurs : Pierre, sur recommandation de Claude Code

Contexte

L'étape 0a commence par choisir le code source à partir duquel embarquer le moteur, derrière une interface C moteur.h qui doit offrir cinq fonctions : initialisation, coups légaux, classement des coups par niveau, décision de videau en match, évaluation. Positions au format GNU Position ID et Match ID. Les résultats doivent concorder avec le GNU Backgammon de bureau, qui sert de référence aux tests.

Trois candidats ont été étudiés par un sous-agent, sur clones superficiels lus sans rien compiler ni exécuter (MR !1 sur git.sans.pub) :

Source Commit étudié Date
gnubg officiel 14b67984737ded0f6de43d63dcb789f729d9b06b (1.08.003) 2026-10-23
gnubg-nn 595a9e8f1fe094ee22db5a736bc05027643756df 2025-09-07
CBG (github.com/clavierhaus/gnubg-android) 62028573d7564275a7c9363f0ef5d4b63d8d0f26 (moteur gnubg b1b2772c) 2026-10-26
Critère gnubg gnubg-nn CBG
Activité Active (corrections régulières) Quasi arrêtée (outil d'entraînement des réseaux) Très active ; un mainteneur, code très majoritairement écrit par IA
Licence GPLv3 ou ultérieure 48 fichiers en GPLv2 seule : incompatible GPLv3 ou ultérieure ; noms « CBG » et « Clavierhaus » revendiqués comme marques
Fonctions Les cinq, avec tables d'équité, Crawford, Jacoby, Position ID et Match ID Partiel : pas de Match ID, videau réimplémenté en C++ Les cinq, mais interface pensée pour une partie en cours
Dépendances GLib dans tout le cœur, remplaçable par un shim d'environ 30 fonctions, sauf GMarkup (tables d'équité) et g_mapped_file ; SSE, AVX, NEON et repli en C générique ; threads désactivables C++14, Python 2, SSE seul GLib, GObject et libintl compilés en entier pour Android
Isolement Faisable : environ 24 400 lignes ; état global partout ; backgammon.h à réduire Évaluation isolée, le reste à réécrire 41 fichiers et 681 lignes de bouchons : pas une bibliothèque minimale
Données gnubg.weights (1 097 796 octets) ; gnubg.wd, gnubg_os0.bd, gnubg_ts0.bd générés au build ; tables d'équité XML (Kazaross-XG2.xml par défaut) Pas de poids fournis Mêmes poids, identiques octet pour octet ; aucune base .bd fournie
Portabilité NEON présent ; pas de SIMD WebAssembly (C générique) ; un portage Emscripten tiers existe (hwatheod/gnubg-web, 2019) Mauvais point de départ Build CMake/NDK fonctionnel, pas de WebAssembly
Concordance Mêmes sources et poids que le bureau ; écart flottant car configure.ac force -ffast-math Non, pour le videau Écarts de 1e-4 à 3e-3 selon leur documentation, non vérifié

Points recoupés directement dans les sources par la session principale : les 48 en-têtes GPLv2 de gnubg-nn (ex. gnubg-nn/gnubg/eval.c l. 7) ; la licence GPLv3+ de gnubg/eval.c ; -ffast-math ajouté par gnubg/configure.ac:595 ; le code NEON dans lib/simd.h et lib/neuralnetsse.c ; l'identité des poids entre gnubg et CBG ; trois usages de g_markup dans matchequity.c ; makebearoff dans Makefile.am.

Décision

Le moteur d'Ustagammon est construit à partir de GNU Backgammon officiel, figé au commit 14b67984737ded0f6de43d63dcb789f729d9b06b, dont on n'extrait que le cœur, derrière moteur.h.

Fichiers à reprendre (liste issue des #include et des symboles, à confirmer à la première édition des liens) :

  • Évaluation : eval.c/h, movefilters.inc, lib/neuralnet.c/h, lib/neuralnetsse.c, lib/inputs.c, lib/simd.h, lib/sigmoid.h, lib/cache.c/h, lib/gnubg-types.h, lib/isaac.c/h, lib/isaacs.h, lib/md5.c/h.
  • Fin de partie : bearoff.c/h, bearoffgammon.c/h.
  • Identifiants : positionid.c/h, matchid.c/h.
  • Équité de match : matchequity.c/h, mec.c/h, lib/list.c/h.
  • En-têtes à réduire : backgammon.h, common.h, multithread.h, util.h.
  • Données : gnubg.weights, met/*.xml ; outils hôte makeweights.c et makebearoff.c.

Plan d'isolement :

  1. Copie figée dans engine/, config.h écrit à la main (sans threads ; NEON sur arm64 ; rien en WebAssembly).
  2. Shim glib.h minimal ; mmap ou fread à la place de g_mapped_file.
  3. Tables d'équité converties en tableaux C au build, ou table Zadeh intégrée pour commencer.
  4. En-tête réduit à la place de backgammon.h, variables globales aux valeurs par défaut de gnubg.c, en s'inspirant de jni-bridge/src/stubs.c de CBG.
  5. Façade moteur.h sur GenerateMoves, FindnSaveBestMoves, GeneralCubeDecisionE et FindCubeDecision, PositionFromID, MatchFromID.
  6. gnubg.wd et bases .bd générées sur l'hôte avec les outils officiels.
  7. Tests de concordance avec tolérance, en mesurant l'écart avec et sans -ffast-math.

Alternatives écartées

  • gnubg-nn : 48 fichiers sous GPLv2 seule, incompatibles avec la GPLv3 du projet ; videau réimplémenté, donc sans concordance possible avec gnubg de bureau.
  • CBG : même moteur, mais avec GLib complète et toute la logique de partie ; interface orientée partie en cours ; pas de bases de fin de partie. Gardé comme référence de lecture, sans reprise de code ni de ses noms.

Conséquences

  • Le gnubg de bureau de référence est compilé dans Docker depuis le même commit, et non pris dans un paquet Debian d'une autre version.
  • Concordance au bit près impossible entre x86 avec -ffast-math et ARM ou WebAssembly : les tests ont une tolérance, et prévoient le cas où le meilleur coup change entre deux coups presque équivalents.
  • L'état global de gnubg impose une seule instance du moteur et des appels sérialisés.
  • Les mises à jour de gnubg sont reportées à la main sur la copie figée.
  • Les tailles des bases .bd restent à mesurer.
  • Attention aux noms de niveaux : gnubg compte les plis à partir de 0 (0-ply = évaluation statique).