Laboratoire · moteurs d'échecs classiques
Faire rejouer les moteurs classiques
Fritz, Junior, Shredder, Nimzo, Hiarcs — les grands moteurs de 1997 à 2005 sont enfermés dans le logiciel ChessBase qui les a vus naître. Deux petits ponts les libèrent : ils les font passer pour des moteurs UCI ordinaires, afin qu'on puisse enfin les faire jouer et les calibrer dans les interfaces modernes.
Ce qu'on cherche à faire
Un moteur d'échecs moderne est un programme autonome qui dialogue en texte, selon un langage universel appelé UCI : l'interface lui envoie une position, il répond son coup. C'est ce langage que parlent toutes les interfaces d'aujourd'hui, et c'est lui qui permet de faire s'affronter des moteurs de toutes origines.
Les vieux moteurs ChessBase, eux, ne fonctionnent pas ainsi. Ce ne sont pas des programmes autonomes mais des modules internes : seul le logiciel d'origine sait les charger et les faire parler. Impossible, tel quel, de les brancher sur une interface moderne — ils restent muets.
L'idée des ponts est de se glisser à la place du logiciel d'origine. Le programme charge le vieux moteur, lui parle exactement comme le faisait le logiciel d'époque, récupère le coup choisi, puis le retraduit en UCI. Vu de l'extérieur, le vieux moteur devient un moteur UCI comme les autres.
Deux ponts, seize moteurs
Les moteurs ChessBase ne sont pas tous bâtis pareil, d'où deux outils :
eng2uci.py— pour les moteurs livrés sous forme de fichier.eng(Fritz, Deep Fritz, Junior, Shredder 7, les Tiger, Hiarcs, Nimzo). Il reconnaît le moteur à la taille exacte du fichier.shredder2uci.py— pour Shredder 5.32 et Shredder 6, qui exposent directement une bibliothèque.dllet se pilotent d'une tout autre façon.
Les moteurs pris en charge
Tous tournent désormais comme des moteurs UCI natifs — coups légaux, promotions, roques, prise en passant, gestion du temps, et depuis août 2026 détection des répétitions et de la règle des cinquante coups (voir plus bas). La colonne taille est essentielle : c'est elle qui sert d'identification.
| Moteur | Fichier | Taille (octets) | État | À savoir |
|---|---|---|---|---|
| Fritz 5.32 | .eng | 126 976 | OK | Le doyen (1997). Format interne un peu différent des suivants (cases échangées). |
| Fritz 6 | .eng | 311 296 | OK | La première version mise au point, référence de tout le reste. |
| Fritz 7 | .eng | 434 176 | OK | Évaluations et meilleur coup lus dans le canal de rapport (voir plus bas). |
| Fritz 8 | .eng | 471 040 | OK | Même base que la 7. |
| Fritz 9 | .eng | 446 464 | OK | Réclame MSVCR71.dll et vérifie la présence du CD — les deux sont gérés. |
| Deep Fritz 8 | .eng + .dll | 487 424 | OK | Le seul vrai multiprocesseur du lot. Les noms de fichiers doivent contenir des
espaces (Deep Fritz 8.eng) : la coquille se cherche elle-même sous ce nom. |
| Junior 7 | .eng + .dll | 212 992 | OK | Même taille que la 8 : distingués automatiquement par une signature interne. |
| Junior 8 | .eng + .dll | 212 992 | OK | Ignore les limites de profondeur : à piloter au temps, jamais en go depth. |
| Hiarcs 7 | .eng + .dll | 155 648 | OK | Protection par contrôle de volume, contournée. |
| Hiarcs 8 | .eng + .dll | 245 760 | OK | Trois contrôles successifs à l'initialisation, tous neutralisés. |
| Nimzo 8 | .eng + .dll | 202 240 | OK | Le fichier Nimzo_8.cmp n'est pas un exécutable mais la base de
combinaisons : il doit simplement rester à côté du .eng. |
| Shredder 7 | .eng + .dll | 86 016 | OK | Le .eng charge Shredder7.dll, qui vérifie le CD — contourné. |
| Chess Tiger 15.0 | .eng + .dll | 114 688 | Jouable | Le plus fiable des deux Tiger, mais écarté de l'échelle de calibration (voir encadré). |
| Gambit Tiger 2.0 | .eng + .dll | 98 304 | Instable | Se corrompt de lui-même sur certaines positions ; écarté de la calibration. |
| Shredder 5.32 | .dll | — | OK | Piloté par shredder2uci.py (pas par eng2uci.py). |
| Shredder 6 | .dll | — | OK | Idem. Multi-thread d'origine, ramené à un seul processeur pour des mesures comparables. |
Il a circulé plusieurs éditions d'un même Fritz (versions localisées, mises à jour, rééditions), qui n'ont pas toutes exactement la même taille de fichier. Le pont identifie le moteur par sa taille : si votre fichier ne fait pas le compte à l'octet près, il s'arrêtera avec un message du type « taille non reconnue » suivi de la liste des tailles connues.
Ce n'est pas un échec : cela signifie simplement que votre édition n'a pas encore été
analysée. Les adresses internes diffèrent d'une édition à l'autre, et les reprendre
demande une passe de rétro-ingénierie dédiée. Vérifiez la taille exacte par un clic
droit → Propriétés sur le fichier .eng.
Télécharger les ponts
eng2uci.py
Le pont principal, en un seul fichier. Gère les quatorze moteurs à fichier .eng :
les cinq Fritz, Deep Fritz 8, les deux Junior, les deux Hiarcs, Nimzo 8, Shredder 7
et les deux Tiger.
shredder2uci.py
Le pont dédié à Shredder 5.32 et Shredder 6, qui se pilotent directement par
leur bibliothèque .dll.
py -3-32 --version doit
répondre sans erreur.
Le dossier à préparer
Un dossier par moteur, contenant :
eng2uci.py— le pont ;Chess32.dll— le petit relais que les moteurs.engréclament ;- le fichier du moteur, par exemple
Fritz 6.eng; - la DLL associée quand le moteur en a une :
Shredder7.dll,Tiger_g.dll,Tiger15.dll,hiarcs7.dll,Hiarcs8.dll,Jr_70.dll,Jr_80.dll,Nimzo_8.dll,Deep Fritz 8.dll; - pour Fritz 9 uniquement :
MSVCR71.dll; - pour Nimzo 8 :
Nimzo_8.cmp.
Pour Shredder 5.32 et 6, le dossier contient shredder2uci.py et la DLL du
moteur (pas de .eng, pas de Chess32.dll).
Utilisation dans Banksia
Banksia est l'interface recommandée : elle pilote les ponts sans configuration exotique.
- Dans Banksia, ouvrir Engines puis Add.
- Au champ Fichier du moteur (l'exécutable), indiquer le chemin du
Python 32 bits, typiquement :
C:\Users\...\Python313-32\python.exe
- Au champ Dossier de travail, indiquer le dossier préparé.
- Au champ Ligne de commandes, passer le pont suivi du nom du fichier
moteur, entre guillemets s'il contient une espace :
eng2uci.py "Fritz 6.eng"… ou, pour Shredder 5.32 / 6 :shredder2uci.py shredder6.dll
- Choisir le protocole UCI, puis valider. Banksia interroge le moteur : il doit répondre son nom et son auteur.
- Régler la taille de hash, créer un tournoi, choisir la cadence et lancer.
uci
isready
position startpos
go depth 8
bestmove.
En ajoutant l'option --calib juste après le nom du script, on obtient une trace
détaillée, utile en cas de problème.
Utilisation dans Arena
Arena fonctionne aussi. Comme il préfère pointer vers un lanceur unique, le
plus simple est de créer à côté du moteur un petit fichier lancer.bat d'une ligne :
- Menu Engines → Install New Engine.
- Sélectionner le
lancer.batqu'on vient de créer. - Quand Arena demande le type de moteur, choisir UCI.
- Vérifier que le dossier de travail pointe bien sur le dossier du moteur.
- Le moteur apparaît dans la liste, prêt à jouer ou à analyser.
Ce que ces moteurs ont dans le ventre
Un pont ne suffit pas : encore faut-il que le moteur joue juste. Plusieurs pièges n'apparaissent qu'en partie réelle, et valent d'être signalés à qui voudrait refaire le chemin.
L'évaluation affichée
Sur Fritz 6, 7 et 8, la valeur la plus visible en mémoire n'est pas l'évaluation : c'est un score de tri interne, environ deux fois et demie trop optimiste. Le pont lit désormais le champ correct, porté par le canal de rapport du moteur, ce qui donne une évaluation conforme à celle du logiciel d'origine — y compris les annonces de mat.
Le meilleur coup, et l'affaire des promotions fantômes
Ce même tableau de tri servait aussi à désigner le coup à jouer, en y prenant simplement la meilleure valeur. Erreur : dans les positions où plusieurs coups atteignent la même borne de mat, le tableau les donne à égalité, et le choix retombait au hasard de l'ordre interne. Conséquence observée en partie : trois promotions en cavalier alors que le moteur annonçait le mat — dont une qui a transformé une victoire en nulle par matériel insuffisant. Le pont lit maintenant le coup déclaré par le moteur dans son canal de rapport ; le tableau ne sert plus que de secours.
Le codage des coups
Chez les Tiger, un bit signale une prise là où les autres moteurs signalent une promotion. Mal interprété, il produisait des coups impossibles — et autant de parties perdues sur coup illégal. Le pont vérifie désormais qu'un pion se trouve bien sur la case de départ avant de conclure à une promotion.
La gestion du temps
Ces moteurs ne vérifient l'ordre d'arrêt qu'à intervalles ; certains débordent de plusieurs secondes. Le pont anticipe l'arrêt, plafonne le temps par coup, et rend malgré tout un coup si le moteur tarde. En cadence à la pendule, il répartit le temps selon le nombre de coups restants annoncé par l'interface.
Deuxième partie · calibration Elo
Calibrer les moteurs adaptés
Faire rejouer ces moteurs n'était que la première moitié du travail. Un moteur peut jouer des coups parfaitement légaux et pourtant ne plus jouer à son niveau. La seule façon de trancher est la calibration : plusieurs centaines de parties contre des adversaires dont la cote est déjà établie, puis le calcul d'une performance Elo qu'on confronte à celle de la version d'origine.
La méthode
Banksia reste l'interface conseillée pour utiliser les moteurs au quotidien. Pour mesurer, on lui a préféré cutechess-cli, l'outil en ligne de commande qui sert de référence aux grandes listes de calibration. Le protocole est identique pour tous :
- quinze secondes par coup, cadence fixe ;
- table de hachage de 512 Mo ;
- livre d'ouvertures Perfect 2023 ;
- une vingtaine de parties contre chacun de trois adversaires UCI de niveau voisin, choisis dans notre échelle maison (Ruffian, SOS, List, Shredder 10, Fruit…) ;
- mesure à un seul processeur pour tous, sauf Deep Fritz 8, seul vrai moteur multiprocesseur du lot, mesuré et publié en huit threads.
La performance est ancrée sur les cotes connues des adversaires, par la formule habituelle : perf = cote adverse + 400 · log10(p / (1 − p)).
Première campagne : un verdict sévère
Les premières mesures, faites au printemps 2026, donnaient un tableau décourageant. Tous les moteurs adaptés perdaient de cent à deux cents points par rapport à leur version native, et la famille Fritz s'effondrait au point d'en paraître inexploitable. La conclusion publiée alors était que cet écart constituait une signature du pont : quelque chose de l'environnement d'époque ne serait pas reproductible, et il faudrait s'en accommoder.
| Moteur adapté | Perf. première campagne | Cote native | Écart |
|---|---|---|---|
| Deep Fritz 8 (py) | 2776 | — | — |
| Shredder 6 (py) | 2705 | 2814 | −109 |
| Hiarcs 8 (py) | 2599 | 2768 | −169 |
| Junior 8 (py) | 2588 | 2758 | −170 |
| Junior 7 (py) | 2500 | 2717 | −217 |
| Hiarcs 7 (py) | 2510 | 2617 | −107 |
| Nimzo 8 (py) | 2450 | 2629 | −179 |
| Fritz 8 (py) | 2707 | 2804 | −97 |
Résultats de la première campagne, aujourd'hui périmés : ils mesuraient un défaut du pont, pas la force des moteurs. Conservés ici comme repère de départ.
Un détail aurait dû mettre la puce à l'oreille : l'écart était trop constant d'un moteur à l'autre, et trop indifférent à leur famille. Une faiblesse de recherche ne se distribue pas si régulièrement. Il ne s'agissait pas d'un manque de force, mais d'un manque d'information.
Le diagnostic : l'historique manquant
En reprenant non plus les scores mais les parties elles-mêmes, l'anomalie a sauté aux yeux. Sur les vingt-trois premières parties de Hiarcs 8, les onze nulles étaient toutes des triples répétitions, et dans au moins cinq d'entre elles le moteur répétait alors qu'il était gagnant — l'adversaire lui-même s'évaluant entre −1,2 et −3,6. Dans une partie, Hiarcs donnait lui-même les échecs perpétuels qui lui coûtaient le point, avec une tour et un fou d'avance.
Le désassemblage a livré l'explication. Les coquilles ChessBase possèdent depuis toujours un mécanisme de rejeu de la partie : l'interface d'époque leur transmettait, à chaque coup, la liste des coups déjà joués, que le moteur rejouait en interne pour reconstituer son propre enregistrement. Ce mécanisme se trouve à quelques octets fixes de la structure de paramètres, et il est présent dans toutes les coquilles examinées — les six Fritz, les deux Hiarcs, les deux Junior, Nimzo.
Les correctifs
- Rejeu de l'historique sur les onze moteurs à coquille ChessBase, selon deux variantes : les moteurs monolithiques (les Fritz) rejouent la liste eux-mêmes, les moteurs à DLL séparée (Hiarcs, Junior, Nimzo) la font rejouer à leur bibliothèque.
- Rejeu limité à la fin de partie utile : on ne retransmet que les coups postérieurs à la dernière prise ou au dernier coup de pion. C'est mathématiquement suffisant — aucune position ne peut répéter quelque chose d'antérieur à un coup irréversible — et cela garde les compteurs internes du moteur dans leur domaine de validité.
- Meilleur coup et évaluation lus dans le canal de rapport pour Fritz 6, 7 et 8 : fin des promotions fantômes, et scores enfin conformes.
- Garde-fous assainis. Un filet de sécurité destiné à rattraper d'éventuels refus du moteur se déclenchait en réalité à tort, et retirait l'historique qu'il était censé protéger — exactement dans les finales où il servait. Il a fallu cinq expériences successives pour établir que les centaines d'incidents journalisés étaient de fausses alertes : le moteur n'avait jamais rien refusé.
Deuxième campagne : les premiers résultats
La re-calibration complète est en cours. Le premier moteur mené jusqu'au bout de la nouvelle procédure donne la mesure de ce qui était en jeu.
| Moteur | Avant | Après correction | Cote native | Écart au natif | Parties |
|---|---|---|---|---|---|
| Hiarcs 8 (py) | 2599 | 2744 ± 36 | 2768 | −24 (n. s.) | 94 |
| Fritz 8 (py) | 2707 | 2769 ± 76 | 2804 | −35 (n. s.) | 22 |
« n. s. » : écart non significatif, inférieur à l'incertitude de mesure. Fritz 8 est un résultat provisoire, obtenu sur une seconde machine dont le facteur de compensation reste à valider.
Cent quarante-cinq points récupérés sur Hiarcs 8, et un écart résiduel avec la version native qui n'est plus distinguable de zéro. La qualité des parties a changé de nature autant que le score : les onze nulles par répétition du départ sont devenues onze nulles réparties sur quatre causes réglementaires différentes — répétition, cinquante coups, matériel insuffisant, pat — toutes à égalité réelle. Le moteur va désormais au bout des finales.
Une seconde leçon, coûteuse, mérite d'être partagée. Faire tourner plusieurs tournois en même temps sur une machine à seize cœurs invalide toutes les mesures, et pas seulement en les ralentissant. La perte n'est pas la même pour tout le monde : un moteur adapté paye deux fois (sa recherche et la couche Python), un moteur multiprocesseur vole les cœurs de ses adversaires, et les processeurs modernes à cœurs hétérogènes ajoutent leur propre loterie. On a vu un même moteur passer de 75 % à 40 % en cours de tournoi, simplement parce que d'autres calculs avaient démarré à côté.
La règle est donc devenue absolue : un seul tournoi à la fois, machine dédiée. Les mesures faites autrement ont été jetées, y compris quand elles étaient flatteuses.
Ce qui reste à faire
- Terminer la calibration de Hiarcs 8 (120 parties), puis re-calibrer dans l'ordre Deep Fritz 8, les cinq Fritz, Junior 7 et 8, Nimzo 8 et Hiarcs 7.
- Pour Deep Fritz 8, un triptyque en conditions strictement identiques : version native, version adaptée sans historique, version adaptée avec historique. C'est la comparaison la plus directe qu'on puisse faire entre un moteur et son propre pont.
- Les trois Shredder n'ont pas encore d'historique : leur structure interne est différente et demande sa propre passe de rétro-ingénierie. C'est le prochain gisement.
- Rétablir l'émission des évaluations dans le mode de gestion du temps interne, où le moteur reste muet sur les recherches courtes — sans effet sur la force, mais on y perd un indicateur utile.
- Valider le facteur de compensation d'une seconde machine, en y refaisant tourner un moteur déjà calibré : c'est la seule façon honnête de doubler la cadence de mesure.
- Explorer Fritz 13 SE, d'une toute autre génération : plus de table de fonctions, un protocole à commandes sérialisées et un mécanisme de signature. Chantier ouvert, sans promesse.
La leçon de la première partie tenait en une phrase : un moteur ne se juge qu'en partie réelle. La seconde en ajoute deux. Un moteur ne se calibre qu'en plusieurs centaines de parties — et quand l'écart mesuré est trop régulier pour être honnête, ce n'est pas le moteur qu'il faut interroger, mais l'outil qui le mesure. Il aura fallu regarder les parties, et non les tableaux, pour s'apercevoir que ces vieux moteurs ne perdaient pas leur force : on leur avait simplement retiré la mémoire de ce qu'ils venaient de jouer.
chess.lumn.eu · laboratoire de calibration