Coder un jeu de morpion / tic-tac-toe en bash sous Linux
Salut les amis, ce petit post fait suite à la dernière vidéo que je viens d’uploader sur youtube et qui concerne l’écriture d’un jeu de morpion (tic-tac-toe en anglais) en bash sous Linux. Alors clairement le bash n’est pas forcément le langage le plus adapté pour ça, et ce n’est pas le genre de choses que j’ai l’habitude d’écrire, le défi m’ayant été lancé par un étudiant de faire un morpion en bash, je me suis dit, pourquoi pas :)
Pour consulter la vidéo :
Quelques explications complémentaires : avant de démarrer l’écriture du script, je suis aller voir les quelques exemples qui existaient sur internet. Ils avaient à peu près tous certaines caractéristiques communes à savoir : l’utilisation d’un tableau pour représenter la grille, et soit un chiffre, soit une lettre qui était affichée dans chaque case du tableau afin d’indiquer la position à jouer.
Du coup j’ai choisi une approche différente par principe. J’ai « dessiné » un tableau moins moche que la plupart que j’ai peu trouver et qui me faisaient mal aux yeux, et j’ai entrepris de baser l’entrée des X et O dans les cases sur les coordonnées à la manière d’une bataille navale. Comme il n’y a donc pas de caractère visible par défaut présent dans les cases, j’initialise (je vide) les cases du tableau en les remplaçant par un espace pour éviter une déformation, ce qui donne donc comme résultat final :
J’ai pris tout un tas de décisions « au fil de l’eau » et il y a bien entendu des dizaines de manière différentes de faire. Par exemple pour check si la position est déjà prise je regarde si elle contient un O ou un X, mais je pourrais très bien simplement vérifier par exemple si elle contient quelque chose différent de l’espace que j’y ai mis.
J’ai utilisé plusieurs fois case au lieu de if / elif, car vu le nombre de cases, cela permet je trouve d’avoir quelque chose de beaucoup plus lisible, cf :
Je me suis également souvenu dans les exemples de code que j’avais lu juste avant, que les conditions de victoires étaient peu lisibles (8 conditions) dans une série de « if », j’ai donc préférer déporter dans une fonction checkline(). ce qui donne quelque chose de beaucoup plus lisible pour écrire et vérifier les conditions des 8 positions :
Remarque : j’ai mis la fonction check_line à l’intérieur de la fonction check_victory : aucun intérêt particulier, si vous la mettez en dehors elle fonctionnera très bien, c’était juste l’occasion pour moi de montrer que c’était possible (même si ce n’est réellement utile que dans certains cas particuliers)
Enfin j’ai eu un peu d’hésitation sur l’écriture de la fonction principale « game_start », sans doute parce que je l’ai écrite à la fin et non pas au début, du coup je n’avais pas vraiment d’idée à l’avance du comment gérer l’écoulement des tours.
On pouvait utiliser while, util, peut être for, et se baser sur le nombre de tours en effectuant une incrémentation à chaque exécution de la boucle. Il était possible également de simplement énumérer les 9 tours 1 par 1 (le moins élégant mais probablement le plus fiable en terme de fonctionnement.
Cependant, comme je n’avais pas séparé en terme de variable la notion de joueur et le contenu des cases O et X, j’ai utilisé une solution intermédiaire qui me permettait de ne pas avoir à modifier une ou plusieurs fonctions précédentes :
J’initialise le premier tour à 1, et le PLAYER à X (c’est toujours X qui commence en général au morpion). Je n’ai pas mis de gestion de « nom de joueur » et reprendre des fonctions m’aurait pris plus de temps, du coup, je n’entre dans la boucle qu’après avoir lancé le premier tour et l’avoir incrémenté.
Ensuite jusqu’à ce qu’il n’y est plus une seule case vide (en réalité contenant espace donc, voir début des explications), je fait tourner O et X un derrière l’autre. J’incrémente le nombre de tour uniquement pour un aspect visuel, mais dans la pratique, cela fonctionne parfaitement sans, puisqu’on ne se base à aucun moment sur lui dans la boucle.
Une fois que toutes les cases sont remplies (et donc s’il n’y a pas eu de victoire avant), alors la partie se termine.
J’ai mis le script sous licence GPL et disponible via le lien suivant : 2b3ts.sh (Brain Bash Tic-Tac-Toe)
—
Christophe Casalegno
​Vous pouvez me suivre sur : Twitter | Facebook | Linkedin | Telegram | Youtube
Laisser un commentaire