2048 est un jeu extrêmement simple: une grille de quatre par quatre carrés et des tuiles numérotées à faire glisser dans quatre directions. Si deux tuiles de même valeur sont poussées l’une contre l’autre, elles s’assemblent en doublant leurs valeurs. À chaque mouvement, une tuile de faible valeur apparaît sur un emplacement libre et la partie dure jusqu’à ce que la grille soit saturée.

Initialement, c’est un jeu solo. Et, honnêtement, il n’y avait pas de raison de le rendre multi-joueur.

Et pourtant…

Et pourtant, je cherchais une excuse pour découvrir les websockets afin de m’initier à la programmation asynchrone. Et comme j’avais déjà codé la logique métier du jeu comme exercice pour approfondir mes connaissances sur les itérateurs du langage Rust 🦀.

Le code

Hébergé sur Gitlab.

Ce dépôt contient à la fois le back-end et le front-end. Tous deux codés en Rust 🦀

Le back-end repose sur la bibliothèque Poem et distribue le front-end utilisant le bibliothèque Yew. Côté utilisateur, c’est un code WebAssembly qui est exécuté dans le navigateur

J’héberge ce jeu sur Render. Dans la version gratuite, les serveurs s’arrêtent au bout de quinze minutes quand aucun joueur n’est présent. Il faudra peut-être attendre une petite minute avant que le jeu n’apparaisse dans ce cas.

L’architecture

En termes de découpage, j’ai séparé le client, le serveur et une petite partie commune aux deux.

  • Le client, c’est la partie Yew qui compile du Rust 🦀 vers du WebAssembly,
  • Le serveur, c’est la partie qui envoie le WebAssembly aux visiteurs et assure la connexion à ces derniers: si un joueur intervient, le serveur reçoit l’instruction, la traite en jouant un tour sur la grille et envoie le nouvel état de la grille à tous les joueurs connectés,
  • La partie commune décrit les actions possibles (les directions, réinitialiser, annuler…).

Il aurait été plus simple de tout laisser dans un seul dépôt et ne pas avoir à partager ces quelques structures entre client et serveur. Seulement voilà, toutes les dépendances du serveur ne compilent pas vers du WebAssembly. Il fallait donc séparer proprement les parties indépendantes, chose rendue “facile” par l’organisation des projets Rust 🦀 via les workspaces 👌

Conclusion

J’étais déjà super content de mon usage des itérateurs en Rust 🦀. Je trouve que c’est d’une rare élégance en termes de programmation.

Pour le reste, j’ai découvert comment faire un GUI et comment fonctionnaient les websockets dans ce langage. Au final, tout marche au top même si, je l’avoue, ce n’est pas le dépôt le plus utile de Gitlab.

Le but initial d’apprentissage est parfaitement atteint.