Qui n'a jamais fait un pendu avec son voisin un jour où il/elle s'ennuyait en cours (
quoique les filles c'est plus du bavardage XD)
Aujourd'hui, nous allons apprendre à faire une version assez simplifiée du pendu pas à pas, et bien expliqué :)
Pour rendre le "cours" plus intéressant, nous allons supposer que je parle à un utilisateur lambda qui posera les questions que vous vous posez en lisant ce tuto
- Citation :
Lambda : bonjour
Bonjour. Nous allons pouvoir commencer le jeu du pendu
Tout d'abord, mettre en oeuvre le programme : un programme se code d'abord dans la tête ou sur le papier avant de se coder sur machine :)
Nous allons donc imaginer comment se déroulera le jeu
Ce sera un jeu à 2 joueurs, le 2ème joueur essaiera de deviner le mot que le 1er joueur a entré...
Voyons comment cela va se passer :
Tout d'abord, le joueur 2 entre le mot à deviner par le joueur 1, ce mot sera stocké dans une chaine, Str1 par exemple
V (comme vie) sera le nombre de vies restantes au joueur 1
R (comme restant) sera le nombre de lettres restantes à trouver
Fin du jeu : V=0 (perdu) ou R=0 (gagné)
Ici, la procédure est plutôt simple, pour d'autres jeux, cela peut être beaucoup plus compliqué...
Mettons donc en oeuvre tout ça
1.Le 2ème joueur rentre le mot à deviner, on vérifie ensuite la validité de la chaine entrée - Code:
-
0->V
While V=0 //tant que la chaine n'est pas valide
0->V //V permettra de savoir si la chaine entrée est valide
ClrHome //efface l'écran
Input "MOT?",Str0 //demande...le mot ^^
//code de vérification de validité
If length(Str0)<23 //1er test: on teste que la taille est valide
Then //oui, la taille est valide
"ABCDEFGHIJKLMNOPQRSTUVWXYZ ->Str9 //caractères valides
1->V
For(Z,1,length(Str0 //on parcourt la chaine
If not(inString(Str9,sub(Str0,Z,1 //cf explications après le code
0->V //chaine non valide
End //fin de la boucle
Else //taille non valide
0->V //chaine non valide
End //fin de la 1ère condition (taille)
End //fin de la boucle while
- Citation :
Lambda : hmm, un peu compliqué tout ça...
Effectivement, mais tout va s'éclaircir avec mes explications
Prenons les 4 cas qui peuvent se présenter et regardons la valeur de V ligne par ligne
- Taille valide et caractères valides
- Code:
-
If length(Str0)<23 //V=0
Then //V=0
"ABCDEFGHIJKLMNOPQRSTUVWXYZ ->Str9 //V=0
1->V //V=1
For(Z,1,length(Str0 //V=1
If not(inString(Str9,sub(Str0,Z,1 //V=1
0->V //Tous les caractères sont valides, V ne change pas : V=1
End //V=1
Else //taille valide, ça ne nous concerne pas
0->V
End
End //fin de la boucle while, finalement V=1
- Taille valide et caractère(s) invalide(s)
- Code:
-
If length(Str0)<23 //V=0
Then //V=0
"ABCDEFGHIJKLMNOPQRSTUVWXYZ ->Str9 //V=0
1->V //V=1
For(Z,1,length(Str0 //V=1
If not(inString(Str9,sub(Str0,Z,1 //V=1
0->V //Un caractère invalide (ou plus) a été trouvé : V=0
End //V=1
Else //taille valide, ça ne nous concerne pas
0->V
End
End //fin de la boucle while, finalement V=0
- Taille invalide et caractères valides
- Taille invalide et caractère(s) invalide(s)
J'ai regroupé ces 2 cas, car le comportement sera le même, puisque étant donné que la taille est invalide, le programme ne testera pas la validité des caractères : elle "sautera" la boucle For() et passera directement au "Else"
- Code:
-
If length(Str0)<23 //non : V=0
Then
"ABCDEFGHIJKLMNOPQRSTUVWXYZ ->Str9
1->V
For(Z,1,length(Str0
If not(inString(Str9,sub(Str0,Z,1
0->V
End
Else //taille invalide
0->V //V=0
End
End //fin de la boucle while, finalement V=0
Finalement c'est bien ce que l'on veut : le programme continuera uniquement si la taille et les caractères sont valides
- Citation :
Lambda : hmm...ok, mais ce serait possible d'expliquer un peu plus le code ?
Oui, j'y viens, je ferais juste une remarque avant : Seules les lettres sont considérées comme des lettres valides ainsi que le caractère espace : si vous voulez inclure par exemple les chiffres, modifiez Str9 et ajoutez-y "0123456789" à la fin
Maintenant, revenons au code : la ligne qui doit sûrement poser problème doit être la ligne
- Code:
-
If not(inString(Str9,sub(Str0,Z,1
On va décomposer cette ligne pour la comprendre :
Tout d'abord,
sub(Str0,Z,1) : cela permet d'extraire le
Zème caractère de la chaine entrée (rappel : Z est la variable qui nous sert à parcourir la chaine du début à la fin)
L'instruction
inString(Str9,
sub(Str0,Z,1 recherche le caractère extrait dans la chaine Str9 : "ABCDEFGHIJKLMNOPQRSTUVWXYZ ". Pour rappel, la fonction inString(
chaine,
sous-chaine) trouve la 1ère occurence de
sous-chaine dans
chaine, ou 0 si
sous-chaine n'a pas été trouvée
(voir tuto sur les chaines de caractères)
Si le caractère extrait n'a pas été trouvé dans Str9, cela retourne donc 0
Le
If not(inString(Str9,sub(Str0,Z,1 permet de vérifier si la fonction inString() a retourné 0 ou non
le not( utilisé ici est une optimisation, not(
expression) est une fonction qui retourne
1 si
expression est non nul,
0 sinon
Ainsi, si le caractère extrait n'a pas été trouvé, inString(Str9,sub(Str0,Z,1 sera égal à 0, donc en prenant le "not()" de tout ça, on obtient
1Vous remarquerez qu'il n'y a pas de signe "=" dans la condition : en effet, en cas d'absence du signe, la condition devient
If ... (différent de) 0
le "(différent de) 0" étant implicite
- Citation :
Lambda : ok, donc je peux écrire
- Code:
-
If 0!=inString(Str9,sub(Str0,Z,1 //!= : différent de
?
Exactement. L'optimisation que l'on a faite a permis de gagner 2 octets
- Citation :
Lambda : c'est rien 2 octets...
Oui, mais c'est toujours 2 octets de gagnés, dans les énormes programmes, un "expert" pourrait gagner 500 octets avec des petits trucs comme ça (ou plus avancés, mais là n'est pas la question)
Une fois la validité de la chaine testée, on passe à la suite...
2.Initialisation des variables de jeuIci, rien de compliqué, il s'agit simplement de stocker des valeurs dans des variables...
- Code:
-
6->V //nombre de vies restantes
length(Str0)-2->R //nombre de lettres restantes
For(Z,2,length(Str0)-1 //parcours de la boucle
If " "=sub(Str0,Z,1 //s'il s'agit d'un espace
R-1->R //on enlève 1 du nombre de lettres restantes
End
0->K //touche pressée
" ->Str2 //lettres déjà proposées
Remarque pour R : -2 pour les lettres de début et de fin et ensuite on enlève tous les espaces
3.Le jeuNous y voilà, le coeur du programme :)
Tout d'abord, afficher le tout
- Code:
-
ClrDraw //efface l'écran de dessin
Text(0,0,sub(Str0,1,1 //premier caractère
For Z,2,length(Str0)-1 //boucle
Text(0,4Z-4,"- //affiche un tiret à la place de la lettre
End
Text(0,4*length(Str0)-4,sub(Str0,length(Str0),1 //dernier caractère
Y a t-il besoin d'explications ici ? On affiche simplement la 1ère lettre, puis on affiche l'un après l'autre les caractères à deviner en les remplaçant par des tirets, et enfin le dernier caractère
Pour faire simple et rapide :
1
| 2
| 3
| 4
| 5
| ...
| length(Str0)-1
| length(Str0)
|
A
| A
| A
| A
| A
| ...
| A
| A
|
A
| -
| -
| -
| -
| ...
| -
| A
|
Nous allons ensuite faire une boucle
tant que il reste des vies et des lettres restantes
tant que ? oui, une boucle while !
- Code:
-
While V>0 and R>0 //tant qu'il reste des vies et des lettres
...
End
On affiche quelques informations pratiques (code à l'intérieur de la boucle !)
- Code:
-
Text(8,0,"Vies restantes=",V
Text(14,0,"Lettres restantes=",R
Text(22,0,"Lettres proposées //A l'extérieur de la boucle
Text(28,0,Str2 //Str2 regroupe les lettres proposées
On attend ensuite qu'une touche soit pressée (évidemment, ce code est à l'intérieur de la boucle...)
- Code:
-
0->K
Repeat K
GetKey->K
End
Note pour le Repeat K : il s'agit encore d'une optimisation, on peut également écrire While K=0 (encore 2 octets)
Rappel : Repeat est "l'inverse" du While : les 2 codes sont équivalents :
- Code:
-
Repeat K=0 //tant que K n'est pas égal à 0
While K!=0 //tant que K est différent de 0
Repeat est plus avantageux lorsqu'il y a plusieurs conditions pour terminer une boucle : en effet, while s'arrête si une seule condition n'est plus verifiée, alors que repeat continue jusqu'à ce que les 2 conditions ne soient plus vérifiées
- Citation :
Lambda : pratique, ça ^^
Une fois qu'on a le code touche, on l'associe au caractère correspondant : attention, ligne de code barbare !
- Code:
-
(K>=51)(K<=93)(5int(.1K)-22+K-10int(.1K))+(K>=41)(K<=43)(K-10int(.1K
If Ans
sub(Str9,Ans,1->Str1
- Citation :
Lambda : o_O ^ 10000
Il s'agit simplement d'une succession de If condensés
Cette ligne peut se ré-écrire de la façon suivante :
- Code:
-
If K>=51 and K<=93
5int(.1K)-22+K-10int(.1K
If K>=41 and K<=43
K-10int(.1K
Je ne vais pas développer cette ligne, il s'agit d'un code retournant le caractère associé à une touche, cela évite les
- Code:
-
If K=41
"A->Str1
If K=42
"B->Str1
...
If K=93
"Z"->Str1
Et permet ainsi un gain de temps, de place et de vitesse considérable
Simplement, le Ans est une variable système qui contient la réponse de la dernière instruction/du dernier calcul.
Une fois le caractère du joueur 1 obtenu, il s'agit de vérifier s'il se trouve dans la chaine proposée par le joueur 2 au départ ; pour cela, il faut se référer au tuto sur les chaines de caractères, car inString() ne suffira pas s'il y a plusieurs fois la même lettre dans le mot :
- Code:
-
If not(inString(Str2,Str1 //Si on n'a pas encore proposé la lettre
Then
0->T //Lettre n'apparait pas
For(Z,2,length(Str0)-1 //parcourt la chaine
If Str1=sub(Str0,Z,1
Then
R-1->R //1 lettre de moins !
1->T //Eh si, elle y apparait !
Text(0,4*Z-4,Str1 //On remplace le tiret par la lettre
End
End
If T=0 //La lettre n'apparait pas...
V-1->V //1 vie de moins !
Str2+Str1->Str2 //On marque la lettre comme proposée !
End
Même principe que pour vérifier la validité, mais beaucoup plus simple :
on part du principe que la lettre proposée n'est pas dans la chaine, alors T=0
On parcourt ensuite la chaine pour voir si elle y est : si oui, on change la valeur de T en 1, sinon T reste en 0 à la fin de la boucle, et on perd une vie
Juste après ce code, vient le End qui clot la boucle While
Et c'est ainsi que se termine le pendu, résumons le code complet :
- Code:
-
0->V
While V=0 //tant que la chaine n'est pas valide
0->V //V permettra de savoir si la chaine entrée est valide
ClrHome //efface l'écran
Input "MOT?",Str0 //demande...le mot ^^
//code de vérification de validité
If length(Str0)<23 //1er test: on teste que la taille est valide
Then //oui, la taille est valide
"ABCDEFGHIJKLMNOPQRSTUVWXYZ ->Str9 //caractères valides
1->V
For(Z,1,length(Str0 //on parcourt la chaine
If not(inString(Str9,sub(Str0,Z,1 //cf explications après le code
0->V //chaine non valide
End //fin de la boucle
Else //taille non valide
0->V //chaine non valide
End //fin de la 1ère condition (taille)
End //fin de la boucle while
6->V //nombre de vies restantes
length(Str0)-2->R //nombre de lettres restantes
For(Z,2,length(Str0)-1 //parcours de la boucle
If " "=sub(Str0,Z,1 //s'il s'agit d'un espace
R-1->R //on enlève 1 du nombre de lettres restantes
End
0->K //touche pressée
" ->Str2 //lettres déjà proposées
ClrDraw //efface l'écran de dessin
Text(0,0,sub(Str0,1,1 //premier caractère
For Z,2,length(Str0)-1 //boucle
Text(0,4Z-4,"- //affiche un tiret à la place de la lettre
End
Text(0,4*length(Str0)-4,sub(Str0,length(Str0),1 //dernier caractère
Text(22,0,"Lettres proposées //A l'extérieur de la boucle
While V>0 and R>0 //tant qu'il reste des vies et des lettres
Text(8,0,"Vies restantes=",V
Text(14,0,"Lettres restantes=",R
Text(28,0,Str2 //Str2 regroupe les lettres proposées
0->K
Repeat K
GetKey->K
End
(K>=51)(K<=93)(5int(.1K)-22+K-10int(.1K))+(K>=41)(K<=43)(K-10int(.1K
If Ans
Then
sub(Str9,Ans,1->Str1
If not(inString(Str2,Str1 //Si on n'a pas encore proposé la lettre
Then
0->T //Lettre n'apparait pas
For(Z,2,length(Str0)-1 //parcourt la chaine
If Str1=sub(Str0,Z,1
Then
R-1->R //1 lettre de moins !
1->T //Eh si, elle y apparait !
Text(0,4*Z-4,Str1 //On remplace le tiret par la lettre
End
End
If T=0 //La lettre n'apparait pas...
V-1->V //1 vie de moins !
Str2+Str1->Str2 //On marque la lettre comme proposée !
End
End
End //fin de la boucle While
Et voilà un joli pendu
pour les cours ^^
Vous pouvez ensuite l'améliorer en ajoutant des graphiques, en permettant plus de caractères, en ajoutant des bonus ou en interdisant de proposer des voyelles, à vous de voir ^^
En tout cas, cela devrait bien aider pour les programmeurs débutants (j'l'espère en tout cas), s'il y a encore des points incompris ou autres choses, faites-moi signe :)
adri>oui, tu peux l'utiliser pour le wiki
Pour conclure, le programme complet en cas d'erreur lors de la copie et la capture d'écran qui va avec
Cliquez sur l'image pour télécharger