Exercices de programmation du jeu du pendu

Présentation

La série d'exercices qui suit permet de programmer une version du jeu du pendu jouable sur smartphone, et qui ressemblera à ça :

Le professeur vous indiquera comment accèder aux exercices et les utiliser. Ce sera probablement en utilisant l'un des deux liens ci-dessous :

Exercice a

Objectifs

Se familiariser avec l'édition d'un fichier source, ainsi que le lancement et l'arrêt du jeu.

Préparation

Ouvrir le fichier pendu.py. Il devrait avoir le contenu suivant :

from workshop.fr.a import *

MONTRER_MOT_SECRET = VRAI

def choisirMot():

go(globals())

La variable booléenne DIVULGUER_MOT_SECRET permet de configurer le jeu pour qu'il affiche le mot à deviner. Sans cette possibilité, il serait compliqué de tester le jeu pour vérifier s'il fonctionne correctement. On donnera à cette variable la valeur VRAI (ou True) tout au long du développement et de la mise au point du jeu, et FAUX (ou False) une fois que le jeu sera au point, pour que le mot à deviner ne soit plus affiché.

Nota : lancer l'exécution de ce fichier en l'état provoquera l'affichage d'un message d'erreur.

Tâches

Écrire le contenu de la fonction choisirMot pour qu'elle retourne toujours la même chaîne de caractères contenant un mot.

Pseudo-code

Retourner un mot contenu dans une chaîne de caractères.

Aperçu

Tests

Exercice b

Objectifs

Offrir la possibilité de définir le mot à deviner grâce au champ de saisie. C'est-à-dire que, lorsqu'on va cliquer sur le bouton Recommencer, c'est le texte contenu dans le champ de saisie qui va être utilisé comme mot à deviner, et donc affiché dans les deux champs.

Préparation

from workshop.fr.b import *



def choisirMot(suggestion):
    …

go(globals())

Tâches

Sachant que :

modifier le code de la fonction choisirMot pour que :

Pseudo-code

Si suggestion est vide
  Retourner un mot quelconque
Sinon
  Retourner suggestion

Aperçu

Le même que pour l'exercice précédent.

Tests

Exercice c

Objectifs

Au lieu de toujours retourner le même mot lorsque le champ de saisie est vide, on va retourner un mot au hasard fournit par le système.

Préparation

from workshop.fr.c import *



def choisirMot(suggestion,motAuHasard):
    …

go(globals())

Tâches

Sachant que :

modifier la fonction choisirMot pour que :

Pseudo-code

Si suggestion est vide
  Retourner motAuHasard
Sinon
  Retourner suggestion

Aperçu

Le même que pour l'exercice précédent.

Tests

Les mêmes que pour l'exercice précédent, sauf que, lorsque le champ de saisie est vide, ce ne sera pas toujours le même mot qui sera affiché. Il se peut qu'un même mot soit affiché deux fois (ou plus) à la suite, mais c'est rare.

Exercice d

Objectifs

Détecter la présence d'une lettre dans un mot.

Préparation

from workshop.fr.d import *



def choisirMot(…):


def lettreEstDansMot(lettre,mot):

go(globals())

Tâches

Sachant que :

écrire le code de la fonction lettreEstDansMot pour que :

Pseudo-code

Si lettre est contenu dans mot
  Retourner VRAI
Sinon
  Retourner FAUX

Aperçu

Lorsque l'on lance le jeu, voilà ce qui est affiché :

Si l'utilisateur clique sur une lettre qui est contenue dans le mot, voici ce qui devrait s'afficher.

Si la fonction ne retourne pas la bonne valeur, et doit donc être corrigée, alors ceci s'affiche :

Si l'utilisateur clique sur une lettre qui n'est pas contenue dans le mot, voici ce qui devrait s'afficher :

Si la fonction ne retourne pas la bonne valeur, et doit donc être corrigée, alors ceci s'affiche :

Tests

Si ce qui est affiché dans Obtenu est barré et surligné de rouge, alors le code de la fonction lettreEstDansMot est incorrect. Noter le mot et le lettre qui posent problème, corriger la fonction, et ressayer le mot et la lettre pour vérifier que le bug a été corrigé.

Exercice e

Objectifs

Affichage du masque, c'est-à-dire du mot à deviner avec dissimulation des lettres qui n'ont pas encore encore été trouvées par le joueur.

Préparation

from workshop.fr.e import *



def lettreEstDansMot(lettre,mot):


def donnerMasque(mot,pioches):

go(globals())

Tâches

Sachant que :

écrire le code de la fonction donnerMasque pour qu'elle retourne mot, mais dont les lettres qui ne sont pas contenues dans pioches sont remplacées par le caractère _.

Pseudo-code

Mettre une chaîne de caractères vide dans masque

Pour lettre étant chaque lettre dans mot
  Si lettre est dans pioches
    Ajouter lettre à masque
  Sinon
    Ajouter le caractère _ à masque

Retourner masque

Aperçu

Tests

Sachant que le contenu du masque est affiché dans le cadre au-dessus du clavier :

Exercice f

Objectif

Dessiner le corps du pendu en fonction du nombre d'erreurs, c'est-à-dire du nombre de lettres choisies par le joueur qui ne sont pas contenues dans le mot à deviner.

Préparation

from workshop.fr.f import *



def donnerMasque(mot,pioches):


def majCorps(nombreErreurs):    

go(globals())

Tâche

Sachant que :

écrire le code de la fonction majCorps pour qu'elle dessine la partie du corps correspondant au nombre d'erreurs.

Pour cette tâche, utiliser la fonction dessinerPartieCorps qui prend, comme paramètre, une des valeurs suivantes :

P_TETE          # pour dessiner la tête,
P_TRONC         # pour dessiner le tronc,
P_BRAS_GAUCHE   # pour dessiner le bras gauche,
P_BRAS_DROIT    # pour dessiner le bras droit,
P_PIED_GAUCHE   # pour dessiner le pied gauche,
P_PIED_DROIT    # pour dessiner le pied droit,
P_VISAGE        # pour dessiner la visage.

maj signifie mise-à-jour, car la fonction est appelée à chaque nouvelle erreur. Cela veut dire que la valeur du paramètre nombreErreurs est incrémenté d'un appel à l'autre. Aussi ne va-t-on pas redessiner tout le corps, mais juste la partie correspondant au nombre d'erreurs.

Pseudo-code

Si nombreErreurs est égal à 1
  Dessiner la tête
Sinon si nombreErreurs est égal à 2
  Dessiner le tronc
Sinon si nombreErreurs est égal à 3
  Dessiner le bras gauche

et ainsi de suite pour dessiner le bras droit, le pied gauche, le pied droit et enfin le visage.

Aperçu

Tests

Exercice g

Objectif

Simplification de la fonction majCorps, grâce à l'utilisation d'un tuple.

Préparation

from workshop.fr.g import *



def majCorps(nombreErreurs):    


go(globals())

Tâches

Pseudo-code

Affecter à PARTIES_CORPS un tuple contenant les constantes P_…

Dessiner la partie du corps stockée dans PARTIES_CORPS correspondant à nombreErreurs

Aperçu

Le même que pour l'exercice précédent.

Test

Les mêmes que pour l'exercice précédent.

Exercice h

Objectif

Lorsque le dernier membre du corps du pendu est dessiné, le visage doit également être dessiné, pour indiquer que la partie est perdue.

Préparation

from workshop.fr.h import *



def majCorps(nombreErreurs):    


go(globals())

Tâches

On pourra se servir de la taille du tuple pour détecter quand est dessinée la dernière partie du corps.

Pseudo-code

Dessiner la partie du corps correspondant à nombreErreurs

Si nombreErreur supérieur au nombre d'erreurs autorisées
  Dessiner le visage

Aperçu

Le même que pour l'exercice précédent.

Tests

Reprendre les tests de l'exercice précédent, et vérifier qu'au lieu d'être dessiné à part, le visage est dessiné en même temps que la dernière partie du corps.

Exercice i

Objectifs

Gérer la lettre sélectionnée par le joueur, de manière à mettre à jour, soit le masque, soit le dessin du pendu en fonction de la présence ou de l'absence dans le mot secret de la lettre sélectionnée (piochée) par le joueur.

Préparation

from workshop.fr.i import *




def majCorps(nombreErreurs):    



bonnesPioches = ""
nombreErreurs = 0


def raz(suggestion,motAuHasard):


def traiterPioche(pioche,motSecret):


go(globals())

Tâches

Fonction raz

Sachant que :

écrire le code de cette fonction pour :

Contrairement à bonnesPioches et nombreErreurs, qui sont des variable globales, motSecret devra être une variable locale.

Le dessin du pendu est effacé automatiquement lorsque l'on clique sur Recommencer.

Fonction traiterPioche

Sachant que :

écrire le code de cette fonctions pour :

Il faudra, bien entendu, utiliser les fonctions développées dans les précedents exercices.

Pseudo-code

Fonction raz

Initialiser variables globales

Choisir un nouveau mot à deviner

Afficher le masque correspondant à ce nouveau mot à deviner

Retourner ce nouveau mot à deviner

Fonction traiterPioche

Si pioche est contenu dans motSecret
  Ajouter pioche à bonnePioches
  Afficher le nouveau masque
Sinon
  Incrémenter nombreErreurs
  Complèter le dessin du pendu

Aperçu

Identique à celui de l'exercice précédent.

Tests

Identiques à ceux de l'exercice précédent.

Exercice j

Objectifs

Comme vous avez pu le constater, la manière dont est codé l'exercice precédent ne permet pas de jouer à ce jeu à plusieurs simultanément. L'objectif de cet exercice est de remédier à cela, grâce à la programmation objet.

Préparation

class Pendu:
  def raz(self):
    self.bonnesPioches = ""
    self.nombreErreurs = 0

  def __init__(self):
    self.raz()
    
  def traiterEtTesterPioche(self,pioche,motSecret):
from workshop.fr.h import *




def majCorps(nombreErreurs):    


# Les déclarations des variables 'bonnesPioches' et 'nombreErreurs'
# qui étaient positionnées ici doivent être supprimées.

class Pendu:
  def raz(self):
    self.bonnesPioches = ""
    self.nombreErreurs = 0

  def __init__(self):
    self.raz()
    
  def traiterEtTesterPioche(self,pioche,motSecret):


def raz(pendu,suggestion,motAuHasard):
# La ligne 'global bonnesPioches, nombreErreurs' présente ici doit être supprimée.
# Le reste du code doit être conservé.

  

def traiterPioche(pendu,pioche,motSecret):
# La ligne 'global bonnesPioches, nombreErreurs' présente ici doit être supprimée.
# Le reste du code doit être conservé.


go(globals())    

Tâches

Au lieu d'être globales à tout le programme, les variables bonnesPioches et nombreErreurs sont maintenant rattachées à une classe appelée Pendu. Une instance de cette classe est crée pour chaque joueur, et est accessible via le paramètre pendu passé aux fonctions raz(…) et traiterPioche(…).

Pour accèder aux membre de cette instance, on utilisera l'écriture pendu.<variable ou méthode>. Ainsi, pendu.nombreErreurs donne accès à la variable nombreErreurs de la classe Pendu, et pendu.raz() appellera la méthode raz de cette même classe.

Dans le cas de méthodes, le premier paramètre, nommé par convention self, est l'instance à partir de laquelle cette fonction a été appelée. Ainsi, en appelant pendu.raz(), le paramètre self de la méthode raz référence la même instance de la classe Pendu que la variable pendu.

Méthode Pendu.traiterEtTesterPioche

Sachant que :

écrire le code de la méthode Pendu.traiterEtTesterPioche pour qu'elle :

Fonction raz

Sachant que :

écrire le code de la fonction raz de manière à ce qu'elle remplisse les même fonctionnalités que dans l'exercice précédent, en utilisant la méthode Pendu.raz pour réinitialiser les variables.

Fonction traiterPioche

Sachant que :

écrire le code de la fonction traiterPioche de manière à ce qu'elle remplisse les même fonctionnalités que dans l'exercice précédent, en utilisant la méthode Pendu.traiterEtTesterPioche développée précédemment.

Pseudo-code

Méthode Pendu.traiterEtTesterPioche

Si pioche est contenu dans motSecret
  Ajouter pioche à bonnePioches
  Retourner VRAI
Sinon
  Incrémenter nombreErreurs
  Retourner FAUX

Fonction raz

Réinitialiser pendu

Choisir un nouveau mot à deviner

Afficher le masque correspondant à ce nouveau mot à deviner

Retourner ce nouveau mot à deviner

Fonction traiterPioche

Si pendu.traiterEtTesterPioche(pioche,motSecret) retourne VRAI
  Afficher le nouveau masque
Sinon
  Complèter le dessin du pendu

Aperçu

Identique à celui de l'exercice précedent.

Tests

Identiques à ceux de l'exercice précédent, en vérifiant que cela fonctionne également avec plusieurs joueurs simultanés.

Exercice k

Objectifs

Prendre en charge la gestion du mot à deviner ainsi que sa (non-)divulgation en fonction de la valeur de la variable globale DIVULGUER_MOT_SECRET.

Préparation

from workshop.fr.k import *




def majCorps(*args):



class Pendu:
  def raz(self,suggestion,motAuHasard):


  def __init__(self):
    self.motSecret = ""
    self.bonnesPioches = ""
    self.nombreErreurs = 0
    
  def traiterEtTesterPioche(self,pioche):



def raz(pendu,suggestion,motAuHasard):

  

def traiterPioche(pendu,pioche):



go(globals())

Tâches

Méthode Pendu.raz

Sachant que :

modifier la méthode Pendu.raz, en s'inspirant de la fonction raz, pour stocker, dans la variable membre Pendu.motSecret, un nouveau mot à deviner.

Fonction raz

Sachant que :

adapter la fonction raz pour prendre en compte les modifications de la méthode Pendu.raz, la gestion du mot à deviner ayant été déléguée à cette méthode de la classe Pendu.

Sachant qu'il existe une fonction divulguerMotSecret(…) qui affiche, afin de facilité les tests, la chaîne de caractère passée en paramètre, modifier la fonction raz de manière à afficher ou non le mot secret en fonction de la valeur de la variable globale DIVULGUER_MOT_SECRET.

Sachant que l'on gère maintenant le mao à deviner motSecret, il n'est plus utile :

Fonction traiterPioche

Sachant que :

modifier le code de la fonction traiterPioche en conséquence.

Pseudo-code

Méthode Pendu.raz

Affecter à pendu.motSecret un nouveau mot à deviner

Réinitialiser les variables membres Pendu.bonnesPioches et Pendu.nombreErreurs

Fonction raz

Réinitialiser pendu

Afficher le masque correspondant au nouveau mot à deviner stocké dans l'instance de la classe Pendu

Si DIVULGUER_MOT_SECRET à VRAI
  Divulguer le mot secret

Fonction traiterPioche

Si pendu.traiterEtTesterPioche(pioche) retourne VRAI
  Afficher le nouveau masque
Sinon
  Complèter le dessin du pendu

Aperçu

Identique à l'exercice précédent, sauf dans le cas où DIVULGUER_MOT_SECRET est à FAUX, auquel cas le champ texte à gauche du bouton Recommencer ne doit pas s'afficher.

Tests

Identiques à ceux de l'exercice précedent, en vérifiant que le champ texte à gauche du bouton Recommencer n'est pas affiché lorsque DIVULGUER_MOT_SECRET est à FAUX.

Exercice l

Objectifs

Gérer les fins de partie, afin de notifier au joueur qu'il a gagné ou perdu, ainsi qu'afficher le nombre d'erreurs et les bonnes pioches lorsque le joueur interrompt une partie en cours pour en commencer une nouvelle.

Préparation

from workshop.fr.k import *




def lettreEstDansMot(lettre,mot)



# Fonction 'donnerMasque' renommée en `donnerMasqueEtTesterSiVictoire`.
def donnerMasqueEtTesterSiVictoire(mot,pioches)


# Fonction 'majCorps' renommée en 'majCorpsEtTesterSiDefaite'.
def majCorpsEtTesterSiDefaite(nombreErreurs):

  self.enCours = VRAI


class Pendu:
  def raz(self,suggestion,motAuHasard):


  def __init__(self):

    self.enCours = FAUX
    
  def traiterEtTesterPioche(self,pioche):



def raz(pendu,suggestion,motAuHasard):

  

def traiterPioche(pendu,pioche):



def AConnexion(pendu,suggestion,motAuHasard):


def APioche(pendu,pioche):


def ARelance(pendu,suggestion,motAuHasard):


go(globals())

Tâches

Fonction donnerMasqueEtTesterSiVictoire

Sachant que :

modifier le code de la fonction donnerMasqueEtTesterSiVictoire (précédemment nommée donnerMasque) pour qu'elle retourne, en plus du masque, la valeur VRAI si le joueur a trouvé toutes les lettres (pioches contient toutes les lettres contenues dans mot), la valeur FAUX dans le cas contraire.

Fonction majCorpsEtTesterSiDefaite

Sachant que :

modifier le code de la fonction majCorpsEtTesterSiDefaite (précédemment nommée majCorps) pour que, en plus de mettre à jour le dessin du corps du pendu, elle retourne la valeur VRAI si le dessin du pendu est complet, FAUX dans le cas contraire.

Rappel : la variable globale P_NOMBRE contient le nombre de parties dont est constitué le dessin du corps du pendu.

Fonction raz

Sachant que :

modifier le code de la fonction raz de manière à tenir compte de ces deux modifications.

Fonction traiterPioche

Sachant que :

Fonction AConnexion

Sachant que :

écrire le code de la fonction AConnexion de manière à initialiser :

On utilisera bien entendu le fonctions développées précédemment.

Fonction APioche

Sachant que :

écrire le code de la fonction APioche de manière à mettre à jour :

On utilisera bien entendu le fonctions développées précédemment.

Fonction ARelance

Sachant que :

écrire le code de la fonction ARelance de manière à :

On utilisera bien entendu le fonctions développées précédemment.

Pseudo-code

Fonction donnerMasqueEtTesterSiVictoire

Mettre une chaîne de caractères vide dans masque
Mettre la valeur VRAI dansvictoire

Pour lettre étant chaque lettre dans mot
  Si lettre est dans pioches
    Ajouter lettre à masque
  Sinon
    Ajouter le caractère _ à masque
    Mettre victoire à FAUX

Retourner masque et victoire

Fonction majCorpsEtTesterSiDefaite

Identique à celui de la fonction majCorps avec, en plus :

Si nombreErreurs >= P_NOMBRE
  Retourner VRAI
Sinon
  Retourner FAUX

Fonction raz

Identique à celui de l'exercice précédent.

Fonction traiterPioche

Si pioche est contenu dans motSecret
  Afficher nouveau masque
  Si partie en cours et victoire
    Notifier victoire
Sinon
  Complèter le dessin du pendu
  Si partie en cours et défaite
    Notifier défaite et afficher informations sur la partie

Fonction AConnexion

Lancer une partie

Fonction APioche

Lancer le traitement de la lettre choisie par le joueur

Fonction ARelance

Si partie en cours
  Afficher informations sur la partie

Lancer une nouvelle partie

Aperçu

Identique à celui de l'exercice précédent

Tests

Identiques à celui de l'exercice précédents.

Vérifier que la détection d'une victoire et d'une défaite est correctement réalisée, et que les notifications sont correctes.

Vérifier qu'un click sur le bouton Recommencer entraîne une notification avec les informations sur la partie en cours, ainsi que le lancement d'une nouvelle partie.