Comprendre l'architecture de Skrabby

Lorsque l'on développe un moteur de Scrabble, la difficulté ne réside pas uniquement dans la recherche des meilleurs coups. Très rapidement, d'autres problématiques apparaissent : comment faire évoluer le moteur sans tout remettre en question? Comment ajouter de nouveaux modes de jeu ? Comment réutiliser les mêmes algorithmes avec différents dictionnaires ou différentes variantes des règles?

Plutôt que de construire une application centrée autour d'une unique classe contenant toute la logique du jeu, Skrabby adopte une architecture modulaire dans laquelle chaque composant possède une responsabilité clairement définie. Les traitements sont isolés dans des contrôleurs spécialisés, les données sont regroupées dans des modèles indépendants, tandis qu'un contexte partagé assure la cohérence de l'ensemble pendant toute la durée d'une partie.

Cette séparation permet au moteur d'évoluer naturellement. Un nouvel algorithme de recherche, un nouveau mode de validation ou une nouvelle variante du jeu peuvent être introduits sans remettre en cause l'architecture existante. Chaque composant reste concentré sur sa propre responsabilité et collabore avec les autres à travers des interfaces bien définies.

Une architecture orientée services

GameControllers.png

Le premier pilier du moteur est constitué des contrôleurs. Ils regroupent toute la logique métier de l'application et orchestrent le déroulement d'une partie. Chacun possède une mission précise : certains pilotent le cycle de vie d'une partie, d'autres recherchent les meilleures solutions, préparent les recherches sur le plateau ou valident les coups proposés. Ensemble, ils forment une chaîne de traitement où chaque service intervient au moment opportun sans empiéter sur les responsabilités des autres.

Cette organisation présente un avantage important : les différents services restent largement indépendants. Le moteur de recherche ne connaît pas les règles de validation, le validateur n'a pas besoin de savoir comment fonctionne le dictionnaire et le contrôleur principal se contente de coordonner les opérations sans réaliser lui-même les traitements. Cette indépendance facilite l'évolution du moteur et limite fortement les dépendances entre les différentes parties du système.

Des modèles centrés sur les données

Gameobjects.png

Face aux contrôleurs se trouvent les modèles. Leur rôle est volontairement limité : ils représentent l'état courant d'une partie. Le plateau, le chevalet, le sac de lettres, les solutions trouvées ou encore l'historique des tours sont autant d'objets décrivant simplement les données manipulées par le moteur.

Contrairement à une approche orientée domaine classique, ces modèles ne prennent aucune décision. Ils ne calculent pas de score, ne recherchent pas de solution et ne connaissent pas les règles du jeu. Toute la logique reste concentrée dans les contrôleurs. Cette séparation simplifie la sérialisation des parties, facilite les tests et permet de réutiliser les mêmes modèles dans différents contextes, qu'il s'agisse d'une partie en cours, d'un replay ou d'une analyse statistique.

CurrentGame : le contexte partagé

Context.png

Pour que ces différents composants puissent collaborer efficacement, Skrabby introduit un troisième élément : CurrentGame. Cette classe ne représente ni un contrôleur ni un modèle. Elle constitue le contexte d'exécution d'une partie et regroupe tout ce dont le moteur a besoin pour fonctionner.

Les contrôleurs, les modèles de données et, lorsqu'une partie est rechargée, son historique, sont réunis dans cette même structure. Chaque service travaille ainsi sur une vision commune de l'état du jeu, sans avoir à transmettre de longues listes de paramètres ou à reconstruire continuellement son environnement de travail.

Cette approche garantit une parfaite cohérence entre les différents composants. Les contrôleurs manipulent les mêmes modèles, partagent les mêmes informations et accompagnent naturellement l'évolution de la partie, du premier tirage jusqu'au dernier coup.

Une base conçue pour évoluer

Cette architecture constitue le socle de Skrabby. Elle ne cherche pas uniquement à résoudre une partie de Scrabble ; elle fournit un cadre suffisamment souple pour accueillir de nouvelles variantes de jeu, différents dictionnaires, de nouveaux algorithmes de recherche ou encore des outils d'analyse et de replay, sans remettre en question les fondations du moteur.

Les prochains articles s'intéresseront à chacun de ces éléments. Nous commencerons par les modèles de données, avant de découvrir le contexte d'exécution, la construction d'une partie et, enfin, le fonctionnement interne des principaux services qui composent le moteur.