# 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).