Nous jouons aussi à CUBE Backgammon, et savoir comment les dés sont générés ne rend pas le troisième double de l’adversaire plus agréable. C’est encore plus agaçant quand l’un de ces jets vient de frapper votre dernier pion exposé.

On retient facilement la frappe qui fait basculer une partie, moins les jets sans conséquence qui l’entourent. Une série de doubles peut aussi sembler exceptionnelle alors qu’une longue partie lui a donné de nombreuses occasions de se produire.

Notre article sur les doubles consécutifs en donne un exemple précis. Obtenir trois doubles sur trois jets désignés à l’avance a une chance sur 216. Une fois le premier double obtenu, la probabilité que les deux suivants soient aussi des doubles est de 1 sur 36. Les deux calculs sont justes, mais ils répondent à des questions différentes. En guettant une série tout au long d’une partie, on lui donne beaucoup plus d’occasions de nous surprendre.

Cela explique une partie des soupçons, sans prouver qu’une application donnée est équitable. Pour CUBE Backgammon, les questions utiles sont donc de savoir comment les dés sont produits et ce que l’on peut vérifier après une partie.

Des octets aléatoires aux six faces du dé

Pour les parties ordinaires contre l’ordinateur, CUBE Backgammon commence par demander des octets au générateur de nombres aléatoires sécurisé de votre appareil. Un octet est un nombre compris entre 0 et 255. Il faut ensuite transformer ces nombres en faces de dés en donnant à chaque face la même probabilité.

Il existe un petit piège lorsqu’on transforme ces octets en dés. Un octet peut prendre 256 valeurs, mais 256 n’est pas divisible par six. Si l’on se contente du reste de la division pour attribuer une face, quatre faces correspondent chacune à 43 valeurs et les deux autres à seulement 42.

Nous écartons les quatre valeurs de 252 à 255 et utilisons les 252 restantes. Chaque face correspond alors à exactement 42 valeurs. Cette méthode, appelée échantillonnage par rejet, évite d’introduire un biais en passant d’octets uniformément répartis aux six faces du dé.

252 valeurs acceptées : 42 pour chaque face
142
242
342
442
542
642

Face du dé en haut, nombre de valeurs en bas. Les quatre autres valeurs sont écartées.

Deux valeurs acceptées forment un jet. Parmi les 36 paires de dés possibles, six sont des doubles : leur probabilité est donc de 1 sur 6. Rien n’impose qu’ils apparaissent une fois dans chaque groupe de six jets, ni qu’un joueur qui vient d’en obtenir plusieurs en reçoive moins ensuite.

Une séquence fixée peut venir du hasard

Plutôt que de demander une nouvelle source aléatoire à chaque tour, une partie ordinaire contre l’ordinateur commence par une graine : une valeur à partir de laquelle on peut reproduire toute la séquence. L’application combine sa contribution aléatoire avec l’instant où vous appuyez sur Démarrer, puis utilise SHA-256, une fonction de hachage cryptographique standard, pour en tirer les dés.

Le générateur de la séquence reçoit cette graine. La position sur le plateau, le niveau de difficulté et le nombre dont l’ordinateur aurait besoin ne font pas partie de ses entrées. Choisir un adversaire plus difficile change sa façon de jouer les jets obtenus.

Reproductible ne veut pas dire choisi à la main. On peut mélanger un jeu de cartes, noter son ordre, puis distribuer : l’ordre est désormais fixé, tout en ayant été choisi au hasard. Les questions importantes sont la manière dont le choix initial a été fait et l’absence de modification ensuite.

Avant le premier jet, l’application calcule aussi une empreinte numérique de la graine, appelée engagement. Lorsque la graine est révélée, on peut recalculer cette empreinte. C’est un élément utile pour vérifier un enregistrement, même si le moment et la manière dont l’empreinte est rendue accessible comptent également.

Ce que vous pouvez reproduire après une partie

Pour les matchs ordinaires enregistrés contre l’ordinateur, le panneau Statistiques des dés conserve des relevés récents. Une fois le match terminé ou abandonné, vous pouvez consulter sa graine, son empreinte et ses jets dans l’ordre, puis appuyer sur Vérifier. Les exemples pédagogiques guidés et les dés fixes utilisés pour le classement initial sont distincts de ces parties ordinaires.

La vérification recrée la séquence à partir de la graine révélée et la compare aux jets enregistrés. Elle contrôle aussi l’empreinte et les limites entre les parties. Modifier un dé dans le relevé sans changer la graine fait échouer la comparaison.

L’exemple ci-dessous applique séparément l’algorithme publié. Vous pouvez reproduire la graine proposée, modifier un jet, ou saisir une graine et une liste de jets provenant d’un match terminé. Tout se fait dans votre navigateur : cet outil ne charge pas votre historique et ne nous envoie pas les valeurs saisies.

Reproduire une séquence

Même graine, mêmes jets. Cet exemple affiche les huit premiers jets de la graine proposée.

Exemple calculé avec la graine cube-dice-example.

Les huit premiers jets de la séquence

  1. 1Jet 1: 1, 4
  2. 2Jet 2: 4, 4
  3. 3Jet 3: 4, 3
  4. 4Jet 4: 3, 3
  5. 5Jet 5: 3, 2
  6. 6Jet 6: 6, 6
  7. 7Jet 7: 5, 5
  8. 8Jet 8: 1, 1
Empreinte de la dernière graine reproduitecf29dd9f3513b834311bbc5e1ca1029730bd9f02fc3af98b82697754e5bfb84a

Reproduire vérifie la cohérence avec une graine, pas la manière dont elle a été choisie. Le bouton Reproduire remplace la liste par huit jets recalculés.

Une vérification utile, avec une limite précise

Si les jets correspondent, on sait que le relevé est cohérent avec la graine. Cela ne suffit pas à établir que le programme a choisi cette graine honnêtement au départ. En théorie, un logiciel pourrait chercher parmi de nombreuses graines avant d’en retenir une, puis produire un relevé parfaitement reproductible.

Un protocole public plus complet rendrait l’engagement initial accessible avant une contribution indépendante du joueur, conserverait les deux contributions et permettrait de vérifier tout l’échange en dehors de l’application. Le relevé après le match et le bouton Vérifier actuels n’apportent pas cette garantie complète. Nous ne les présentons donc ni comme un audit indépendant, ni comme une preuve publique qu’il serait impossible de tricher.

La même distinction vaut pour les statistiques. Compter les faces, les doubles et les écarts entre joueurs peut aider à détecter une erreur de programmation sur un grand nombre de jets. Une courte série équilibrée ne prouve pas l’équité, et une soirée déséquilibrée ne prouve pas la triche.

Ce que nous vérifions pendant le développement

Nous testons la conversion des octets en faces, en passant par chacune des valeurs acceptées et par les quatre valeurs à rejeter. Nous comparons aussi les séquences à des exemples calculés séparément, vérifions que les relevés sauvegardés peuvent être reproduits et les modifions volontairement pour nous assurer que la vérification les refuse.

Ces contrôles cherchent des erreurs différentes : une conversion biaisée, un changement d’algorithme, un relevé endommagé ou une séquence impossible à reproduire. Les vérifications statistiques viennent les compléter.

Avec les mêmes dés, des déplacements de pions différents peuvent donner des positions très différentes. Le coach de CUBE Backgammon vous aide à comparer ces choix pendant la partie et à les revoir dans l’analyse qui suit.

La description des dés ordinaires et de leur relevé a été vérifiée dans le code de CUBE Backgammon. L’outil de cette page est une implémentation de référence séparée, pas un audit de l’application. La spécification Web Cryptography du W3C décrit la source aléatoire du système ; la documentation de libsodium explique pourquoi la conversion doit éviter le biais lié au modulo.

L’algorithme de reproduction

Pour l’algorithme sha256-rejection-v1, on calcule SHA-256 sur les chaînes UTF-8 graine:0, graine:1, graine:2, etc., puis on concatène les octets obtenus. On ignore les octets 252 à 255 ; chaque autre octet donne la face (octet modulo 6) + 1. Deux faces successives forment un jet. L’empreinte est SHA-256 de la graine seule. L’outil accepte jusqu’à 4 096 jets, vérifie le début de la séquence fourni et, si elle est renseignée, son empreinte. Il ne contrôle pas les métadonnées ni les limites entre parties d’un relevé de l’application. Il concerne les matchs ordinaires contre l’ordinateur, pas le protocole serveur du jeu en ligne.