Skip to content
Faire rejouer les moteurs d'échecs classiques — les ponts eng2uci et shredder2uci

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.

Pourquoi le faire Pour donner à ces moteurs historiques une place dans une échelle de calibration Elo : les faire jouer des centaines de parties contre des références, mesurer leur force réelle, et comparer les générations. Sans ces ponts, ils resteraient à jamais prisonniers de leur logiciel d'origine.

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 .dll et 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.

MoteurFichierTaille (octets)ÉtatÀ savoir
Fritz 5.32.eng126 976OK Le doyen (1997). Format interne un peu différent des suivants (cases échangées).
Fritz 6.eng311 296OK La première version mise au point, référence de tout le reste.
Fritz 7.eng434 176OK Évaluations et meilleur coup lus dans le canal de rapport (voir plus bas).
Fritz 8.eng471 040OK Même base que la 7.
Fritz 9.eng446 464OK Réclame MSVCR71.dll et vérifie la présence du CD — les deux sont gérés.
Deep Fritz 8.eng + .dll487 424OK 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 + .dll212 992OK Même taille que la 8 : distingués automatiquement par une signature interne.
Junior 8.eng + .dll212 992OK Ignore les limites de profondeur : à piloter au temps, jamais en go depth.
Hiarcs 7.eng + .dll155 648OK Protection par contrôle de volume, contournée.
Hiarcs 8.eng + .dll245 760OK Trois contrôles successifs à l'initialisation, tous neutralisés.
Nimzo 8.eng + .dll202 240OK 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 + .dll86 016OK Le .eng charge Shredder7.dll, qui vérifie le CD — contourné.
Chess Tiger 15.0.eng + .dll114 688Jouable Le plus fiable des deux Tiger, mais écarté de l'échelle de calibration (voir encadré).
Gambit Tiger 2.0.eng + .dll98 304Instable Se corrompt de lui-même sur certaines positions ; écarté de la calibration.
Shredder 5.32.dllOK Piloté par shredder2uci.py (pas par eng2uci.py).
Shredder 6.dllOK Idem. Multi-thread d'origine, ramené à un seul processeur pour des mesures comparables.
Important : la taille fait foi

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.

script Python · à placer dans le dossier du moteur

shredder2uci.py

Le pont dédié à Shredder 5.32 et Shredder 6, qui se pilotent directement par leur bibliothèque .dll.

script Python · à placer dans le dossier du moteur
Prérequis indispensable Ces moteurs sont en 32 bits : il faut donc un Python 32 bits (les versions 64 bits ne pourront pas les charger). Sous Windows, installer Python puis vérifier depuis un terminal : 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 .eng ré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.

  1. Dans Banksia, ouvrir Engines puis Add.
  2. Au champ Fichier du moteur (l'exécutable), indiquer le chemin du Python 32 bits, typiquement :
    C:\Users\...\Python313-32\python.exe
  3. Au champ Dossier de travail, indiquer le dossier préparé.
  4. 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
  5. Choisir le protocole UCI, puis valider. Banksia interroge le moteur : il doit répondre son nom et son auteur.
  6. Régler la taille de hash, créer un tournoi, choisir la cadence et lancer.
Vérification rapide Avant de lancer un tournoi, un test en ligne de commande confirme tout :
py -3-32 eng2uci.py "Fritz 6.eng"
uci
isready
position startpos
go depth 8
Le moteur doit annoncer sa profondeur qui grimpe, puis un 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 :

py -3-32 eng2uci.py "Fritz 6.eng"
  1. Menu Engines → Install New Engine.
  2. Sélectionner le lancer.bat qu'on vient de créer.
  3. Quand Arena demande le type de moteur, choisir UCI.
  4. Vérifier que le dossier de travail pointe bien sur le dossier du moteur.
  5. 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.

Le cas Gambit Tiger 2.0 Ce moteur se corrompt de lui-même sur certaines positions : il l'annonce d'ailleurs par un message parlant d'un « problème de réentrance » et conseillant de redémarrer le programme. Le pont rattrape l'incident et rend le dernier coup connu au lieu de perdre la partie, mais le moteur reste diminué jusqu'à la fin de celle-ci. Les deux Tiger sont donc jouables pour le plaisir, mais écartés de l'échelle de calibration.

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 campagneCote nativeÉcart
Deep Fritz 8 (py)2776
Shredder 6 (py)27052814−109
Hiarcs 8 (py)25992768−169
Junior 8 (py)25882758−170
Junior 7 (py)25002717−217
Hiarcs 7 (py)25102617−107
Nimzo 8 (py)24502629−179
Fritz 8 (py)27072804−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.

La cause, en une phrase Le pont ne remplissait jamais cette liste. Les moteurs jouaient donc sans aucune mémoire de la partie en cours : aveugles à la triple répétition, aveugles à la règle des cinquante coups. Ils bradaient des positions gagnantes en répétant, sans savoir qu'ils répétaient.

Les correctifs

  1. 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.
  2. 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é.
  3. 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.
  4. 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.

MoteurAvantAprès correctionCote nativeÉcart au natifParties
Hiarcs 8 (py)25992744 ± 362768−24 (n. s.)94
Fritz 8 (py)27072769 ± 762804−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.

Et les Fritz classiques ? La conclusion précédente — « les Fritz de la 5.32 à la 9 ne sont pas exploitables pour une mesure Elo » — était fausse. Ils souffraient du même mal que les autres, aggravé par le bug du meilleur coup. Les cinq passent aujourd'hui les tests de validation, et la première mesure de Fritz 8 le place dans l'intervalle de sa cote native. Leur re-calibration complète est en file d'attente.
La machine est un instrument de mesure

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.
Ce qu'on en fait dans le classement Les moteurs adaptés gardent leur place dans la liste sous leur cote réellement mesurée, jamais celle de leur passé natif, et portent une marque distinctive (couleur et mention « py ») pour qu'on ne les confonde jamais avec un moteur UCI d'origine. Les entrées issues de la première campagne sont progressivement remplacées à mesure que la seconde avance ; d'ici là, elles sous-estiment leurs moteurs d'environ cent cinquante points.

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