Comment créer un Boggle en Python ? Le Boggle, c’est ce jeu de 16 dés sur lesquels sont inscrites des lettres et il faut former le plus de mots possibles avec des lettres qui se suivent.
Les règles du jeu sont disponibles sur la page https://www.boggle.fr/regles.php.
Boggle en Python: préliminaires
Je ne possède pas ce jeu, donc je ne connais pas les lettres mises sur les différents dés.
Par conséquent, je vais créer mes propres dés de façon aléatoire pour chaque partie.
Je voudrais tout de même offrir aux joueurs le possibilité de jouer avec les « vrais » dés. Je vais donc penser à insérer une option pour lire un fichier dans lequel seront mises 16 lignes contenant chacune 6 lettres (plus d’explications plus loin).
À ce stade, il y a donc deux façons de jouer à mon Boggle: soit on impose les dés, soit on laisse la machine les choisir au hasard.
Il y a plusieurs façons de coder. Je vais opter pour la POO. Les personnes qui lisent mes articles régulièrement savent que c’est une façon de coder que j’apprécie.
Boggle en Python: l’implémentation
Boggle et Python: l’objet
Comme je souhaite coder en POO, je vais créer un objet « Boggle », donc une class du même nom.
Le constructeur devra définir deux choses:
- les 16 dés de la partie
- le plateau (formé des 16 dés)
L’objet devra posséder une option « fichier » si toutefois on souhaite imposer les dés du jeu.
Boggle et Python: le constructeur
Pour simplifier les choses, je vais faire appel à deux méthodes pour le constructeur: la méthode « dices » (qui va définir les 16 dés) et la méthode « board » (qui définira le plateau du jeu).
class Boggle(): def __init__(self,fichier = None): self.dices(fichier) self.board()
Ainsi,
>>> B = Boggle()
définit un Boggle avec des dés aléatoirement choisis et
>>> B = Boggle('des.txt')
définit un Boggle dont les dés sont stockés dans le fichier « des.txt » sous la forme de 16 chaînes de caractères formées de 6 lettres majuscules, par exemple:
AJYHFT
HRJNVB
KIKFGV
OPKJHN
KIJHKG
NBVLMI
UJUGHB
NJHURN
NHBCWM
LOLKJH
NJBNHT
PLOKJG
HVNGBV
KJIHKY
NBWQPM
LNYTHG
La méthode « dices »
Cette méthode doit lire le fichier mis en option si on souhaite que les dés soient imposés, et doit choisir au hasard les lettres à mettre sur chacun des 16 dés dans le cas contraire.
Contrairement à mon fichier des.txt précédent, il serait bon de ne pas mettre deux fois la même lettre sur un dé.
Je vais faire appel au module Python string et à sa fonction ascii_uppercase qui retourne les lettres de l’alphabet dans l’ordre et en majuscules.
Je vais aussi faire appel au module Python random et à sa fonction choice.
def dices(self,fichier): self.des = [] if fichier != None: with open(fichier , 'r') as f: for line in f: self.des.append(list(line.replace('\n',''))) else: for _ in range(16): self.des.append([choice(ascii_uppercase) for _ in range(6)])
la liste self.des contiendra 16 listes, chacune d’elles représentant un dé.
La méthode « board »
Dans cette méthode, il faut que je mélange les dés. Je vais donc faire appel à la méthode shuffle du module random.
Je vais d’abord mélanger la liste N = [1,2,3,4,5,6,…,16] et je vais créer une liste self.plateau dans laquelle je vais insérer une lettre (au hasard) d’un dé. À ce stade, n’oublions pas que les dés sont déjà définis. La liste N contiendra le rang du dé à insérer dans self.plateau.
Par exemple, si N = [5,2,9,…], je vais d’abord considérer le dé self.des[5], puis choisir au hasard une lettre de ce dé. Ensuite, je vais prendre le dé self.des[2], et je vais choisir une lettre de ce dé. etc.
Ce qui donne:
def board(self): N = [i for i in range(16)] shuffle( N ) # ordre des dés self.plateau = [] n = 0 for _ in range(4): line = [] for _ in range(4): line.append( choice( self.des[ N[n] ] ) ) n += 1 self.plateau.append( line )
L’affichage du plateau
Maintenant, il faut afficher les lettres. Je vais donc définir l’affichage de l’objet à l’aide de la méthode __str__:
def __str__(self): r = '' for line in self.plateau: for col in line: r += f' {col} ' r += '\n' return r
Ainsi, on a :
>>> B = Boggle()
>>> print( B )
A Q I A
Z N V B
R Z R Y
V J K B
Améliorations
Pour éviter que le fichier (optionnel) contenant les dés ne soit pas conforme à nos attentes, il faudrait insérer des tests.
Je vais donc tester:
- la présence du fichier,
- la longueur de chaque chaîne de caractères (elle doit être égale à 6, car il y a 6 faces à chaque dés),
- la présence de 16 lignes (car il y a 16 dés).
from string import ascii_uppercase from random import choice, shuffle class Boggle(): def __init__(self,fichier = None): self.errors = [] self.dices(fichier) self.board() def dices(self,fichier): self.des = [] if fichier != None: try: with open(fichier , 'r') as f: for line in f: if len( list(line.replace('\n','')) ) == 6: self.des.append(list(line.replace('\n',''))) else: self.errors.append('Erreur de dimension sur la ligne :' + line + 'Chaque ligne doit être de la forme : ABCDEF.') except: self.errors.append('Fichier « ' + fichier + ' » manquant.') if len(self.des) != 16 and len(self.errors ) == 0: self.errors.append('Il n\'y a pas 16 dés.\nVeuillez vérifier que le fichier contient bien 16 lignes.') if len( self.errors ) != 0: for e in self.errors: print(e) else: for _ in range(16): self.des.append([choice(ascii_uppercase) for _ in range(6)]) def board(self): if len(self.errors) == 0: N = [i for i in range(16)] shuffle( N ) # ordre des dés self.plateau = [] n = 0 for _ in range(4): line = [] for _ in range(4): line.append( choice( self.des[ N[n] ] ) ) n += 1 self.plateau.append( line ) def __str__(self): if len(self.errors) == 0: r = '' for line in self.plateau: for col in line: r += f' {col} ' r += '\n' return r else: return '\033[91mPas de plateau.'
Ce qui donne par exemple:
Boggle et Python: quand le fichier n’existe pas
>>> B = Boggle('des.txt')
>>> print( B )
Fichier « des.txt » manquant.
Pas de plateau.
Boggle et Python: quand il manque une ligne
>>> B = Boggle('des.txt')
>>> print( B )
Il n'y a pas 16 dés.
Veuillez vérifier que le fichier contient bien 16 lignes.
Pas de plateau.
Quand il manque une ou plusieurs lettres dans au moins une ligne
>>> B = Boggle('des.txt')
>>> print( B )
Erreur de dimension sur la ligne :KIKFG
Chaque ligne doit être de la forme : ABCDEF.
Erreur de dimension sur la ligne :NHBCW
Chaque ligne doit être de la forme : ABCDEF.
Erreur de dimension sur la ligne :KJIH
Chaque ligne doit être de la forme : ABCDEF.
Pas de plateau.