Références : format des analyses documenté et vérifié
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
242a2433d2
commit
7e958fab8e
@@ -11,14 +11,16 @@ d'un fichier de résultat.
|
||||
| --- | --- |
|
||||
| `positions.json` | Positions d'entrée, versionnées, écrites à la main |
|
||||
| `results/<id>.json` | Résultats de gnubg, un fichier par position, générés |
|
||||
| `generate.py` | Script exécuté dans gnubg qui produit `results/` |
|
||||
| `compare.py` | Compare le moteur embarqué à `results/` (dernière section) |
|
||||
| `analyses.json` | Analyses d'entrée : coups joués, décisions de videau, niveaux de jeu |
|
||||
| `analysis/<id>.json` | Résultats de l'analyse de partie de gnubg, générés (section « Analyses ») |
|
||||
| `generate.py` | Script exécuté dans gnubg qui produit `results/` et `analysis/` |
|
||||
| `compare.py` | Compare le moteur embarqué à `results/` et `analysis/` (dernière section) |
|
||||
|
||||
Commandes :
|
||||
|
||||
```
|
||||
make reference-image # construit l'image Docker du gnubg de référence
|
||||
make reference # régénère results/ (une vingtaine de secondes)
|
||||
make reference # régénère results/ et analysis/ (une quarantaine de secondes)
|
||||
make test # vérifie la cohérence (tests/test_reference.sh) et
|
||||
# compare le moteur embarqué (tests/test_engine_reference.sh)
|
||||
```
|
||||
@@ -222,6 +224,69 @@ Sortie de `gnubg.cfevaluate` (`GeneralCubeDecisionE` puis
|
||||
`TOOGOOD_PASS`, `REDOUBLE_TAKE`, `NODOUBLE_DEADCUBE`…) ;
|
||||
- `decision_text` : le libellé anglais correspondant de gnubg.
|
||||
|
||||
## Analyses : `analyses.json` et `analysis/<id>.json`
|
||||
|
||||
Ce que gnubg dit d'un coup joué, d'une décision de videau et d'un jet de dés
|
||||
(sa commande « analyse game »), et le coup que joue son ordinateur à chaque
|
||||
niveau. Pour chaque cas, `generate.py` rejoue dans gnubg une courte partie
|
||||
entre deux joueurs humains : la position (`set gnubgid`), puis le coup ou la
|
||||
décision, puis l'analyse. Rien n'est calculé dans le script : les valeurs
|
||||
viennent des enregistrements de la partie analysée et des statistiques que
|
||||
gnubg en tire.
|
||||
|
||||
`analyses.json` a trois listes :
|
||||
|
||||
- `moves` : `position_id`, `match_id`, `dice` et `played`, le coup joué en
|
||||
notation de gnubg (`null` : le meilleur coup selon gnubg, pour les cas qui
|
||||
ne servent qu'à la chance du jet) ;
|
||||
- `cubes` : `position_id`, `match_id` (sans dés) et `action`, la décision :
|
||||
`no_double` ou `double` pour le joueur au trait, `take` ou `pass` pour son
|
||||
adversaire ;
|
||||
- `levels` : `position_id`, `match_id` et `dice` (`null` : décision de
|
||||
videau).
|
||||
|
||||
Un fichier de résultat reprend le cas, avec `type` (`move`, `cube` ou
|
||||
`level`), `gnubg_commit` et `met`, puis, aux niveaux d'analyse 0 et 2 plis
|
||||
(clés de `plies`, réglages prédéfinis de gnubg sans bruit, filtre
|
||||
« Normal ») :
|
||||
|
||||
- **coup joué** : `played_move` et `played_position_id` (position après le
|
||||
coup, vue de celui qui l'a joué), `move_count` (coups légaux), `rank` (place
|
||||
du coup joué dans le classement de l'analyse, à partir de 1 ; `imove` de
|
||||
gnubg plus 1), `played_equity`, `best_move`, `best_equity`, `equity_loss`
|
||||
(perte du coup joué, 0 ou négative : statistique « error-skill » de gnubg
|
||||
changée de signe), `skill` (`none`, `doubtful`, `bad`, `very_bad`) et
|
||||
`ranking` (les dix premiers coups, et jusqu'au coup joué) ; plus, une fois
|
||||
pour toutes, `luck` : `value` (chance du jet) et `rating`
|
||||
(`very_unlucky`, `unlucky`, `none`, `lucky`, `very_lucky`) ;
|
||||
- **videau** : `analysed` (gnubg analyse-t-il cette décision ? pas à la
|
||||
partie Crawford ni quand l'adversaire possède le videau), `cube` (la
|
||||
décision de videau de gnubg au même niveau, format de la section
|
||||
précédente, `null` si non analysée), `equity_loss` (perte de celui qui
|
||||
décide, statistique « error-skill » changée de signe) et `skill` ;
|
||||
- **niveaux** (`levels`, à la place de `plies`) : pour les niveaux
|
||||
`beginner`, `casual`, `intermediate`, `advanced`, `0ply`, `1ply` et `2ply`
|
||||
(3 et 4 plis sont trop lents pour la suite de tests), `plies` et `noise`
|
||||
(réglages de gnubg), puis `move`, le coup que joue l'ordinateur de gnubg
|
||||
réglé à ce niveau (commande « play »), ou la décision de videau de gnubg
|
||||
avec ces réglages, bruit compris.
|
||||
|
||||
Deux précautions, faute de quoi gnubg donne des valeurs qui dépendent de ce
|
||||
qu'il a calculé avant :
|
||||
|
||||
- **le cache d'évaluation est vidé avant chaque analyse**, et l'analyse du
|
||||
videau est désactivée pour les coups joués. Une évaluation à 2 plis avec
|
||||
élagage range dans le cache des évaluations à 0 pli faites avec les réseaux
|
||||
d'élagage, sous la même clé que les évaluations à 0 pli ordinaires (la clé
|
||||
d'`EvalKey`, dans `eval.c`, n'inclut l'élagage qu'à partir d'1 pli). Une
|
||||
analyse à 0 pli, ou l'analyse de la chance qui suit l'analyse du videau à
|
||||
2 plis, les reprend : écarts observés de 5e-3 à 2,5e-2. Le moteur embarqué
|
||||
a le même cache ; `compare.py` l'interroge par un processus neuf à chaque
|
||||
commande ;
|
||||
- **le coup choisi pour un cas sans `played` vient de `findbestmove`** et non
|
||||
de « hint », dont gnubg garde l'analyse dans l'enregistrement du coup :
|
||||
« analyse game » la reprendrait au lieu de calculer au niveau demandé.
|
||||
|
||||
## Comparaison avec le moteur embarqué
|
||||
|
||||
`make test` compare le moteur embarqué à ces résultats
|
||||
@@ -264,6 +329,22 @@ Pour chaque position et chaque niveau :
|
||||
- même décision de videau (`decision` et `decision_text`), et les quatre
|
||||
équités du videau à la tolérance près.
|
||||
|
||||
Pour chaque analyse (`engine-cli analysemove`, `analysecube`, `luck`, et
|
||||
`--level NIVEAU bestmove` ou `cube`) :
|
||||
|
||||
- coup joué : même nombre de coups légaux, même notation du coup joué, même
|
||||
rang sauf égalité (les coups entre les deux rangs ont pour gnubg la même
|
||||
équité que le coup joué, à la tolérance près : remarque), même meilleur coup
|
||||
sauf égalité, et `played_equity`, `best_equity`, `equity_loss` à la
|
||||
tolérance près ;
|
||||
- chance : `value` à la tolérance près ;
|
||||
- videau : même `analysed`, même décision et équités à la tolérance près,
|
||||
`equity_loss` à la tolérance près ;
|
||||
- appréciation (`skill`) et chance (`rating`) identiques, sauf si la valeur
|
||||
de gnubg est à moins de la tolérance d'un seuil (remarque) ;
|
||||
- niveaux : mêmes réglages que gnubg (`engine-cli levels`), même coup choisi,
|
||||
ou même décision de videau et équités à la tolérance près.
|
||||
|
||||
Le rapport donne, pour chaque écart hors critères, la position et le niveau,
|
||||
le champ, la valeur attendue (gnubg), la valeur obtenue (moteur) et l'écart ;
|
||||
il donne toujours l'écart maximal observé.
|
||||
@@ -309,6 +390,11 @@ qu'affiche gnubg (trois décimales). Les vrais défauts (mauvais niveau,
|
||||
mauvais contexte de videau, mauvaise conversion d'équité) donnent des écarts
|
||||
d'un ou plusieurs centièmes.
|
||||
|
||||
Mesure du 2026-11-03, avec les 37 analyses (2 890 nombres comparés, natif et
|
||||
WebAssembly) : écart maximal 1,64e-3, sur `move-jacoby` à 2 plis (équité du
|
||||
coup joué `8/2 5/1*`, et donc sa perte), même phénomène de bascule à 2 plis ; tous les autres
|
||||
nombres des analyses restent sous 1e-3. La tolérance n'a pas été changée.
|
||||
|
||||
Sur téléphone (NEON) les écarts seront à mesurer de la même façon : avec
|
||||
`-ffast-math`, gnubg y remplace aussi la division par une approximation
|
||||
(`vrecpeq_f32` et une itération de Newton), différente de celle de SSE2.
|
||||
|
||||
Reference in New Issue
Block a user