Salut à tous ! :) Voici donc mon premier tuto, qui ne sera peut-être pas le dernier du genre ;) .
Le but ? Créer le jeu des allumettes sur votre calculatrice pour vous montrer (en gros) comment on programme sur ces machines.
Ce qui est pratique, c'est que le langage utilisé est vraiment très simple, et il permet une approche de la programmation à la fois rapide et intéressante, car on arrive très vite à faire de beaux jeux !
Quel sera le matériel nécessaire ?
Un cerveau en état de marche
Un crayon et du papier (plus important qu'on ne le pense !)
Bien sûr, une calculatrice. Personnellement je dispose d'une TI-83 plus, les calculatrices supérieures devraient faire l'affaire (ainsi que les TI-83 et 82 mais je ne garantis pas que toutes les fonctions que j'utiliserai soient présentes sur ces machines)
Bonne question non ? Comment qu'on fait pour savoir où commencer ? Il faut d'abord commencer par définir précisément ce que l'on veut faire, admettez que pour l'instant, "le jeu des allumettes" c'est pas très clair ^^ .
Je vais vous expliquer ma version du jeu, mais vous pourrez toujours (et je vous encourage à le faire) la modifier à votre convenance pour vous entraîner à programmer ou pour améliorer le programme (rappelons que la meilleure façon de découvrir de nouvelles choses est de bidouiller !).
On aura donc 36 allumettes disposées sur le tableau de jeu, et chaque joueur (si il n'y a qu'un seul joueur, l'ordinateur se chargera de jouer à la place du deuxième joueur) devra à son tour enlever entre une et six allumettes sans prendre la dernière, car le joueur qui enlèvera la dernière allumette perdra la partie.
Alors, maintenant qu'on connaît les règles du jeu, on peut se lancer ? Eh non ! pas encore ;) .
L'une des raisons récurrentes pour lesquelles certains programmeurs en herbe n'arrivent pas au bout de leurs programmes est qu'ils ne pensent pas leur programme avant de se lancer dans sa réalisation. Ils "foncent tête baissée". Erreur !
Tout bon programmeur, avant de se lancer dans sa tache, se doit de faire un algorigramme de son programme.
Un algori quoi ? o_O
Al-go-ri-gramme. C'est une sorte de plan du programme qui détaille toutes les étapes qu'il devra suivre avant d'arriver à sa fin. Cela permet de ne pas se perdre en cours de route, on sait exactement où on en est et pourquoi on fait ce que l'on fait. Cependant, dans ce tuto, nous ne réaliserons pas un vrai algorigramme, ce serait trop long pour moi de tout détailler (bien qu'il soit relativement simple pour un programme de cette ampleur).
On va donc écrire notre programme simplement, étape par étape en les numérotant pour plus de clarté (vous pouvez l'écrire sur papier pour l'avoir à portée de main, c'est d'ailleurs ce qu'il faudra faire pour vos futurs programmes ;) ) :
Afficher un écran de bienvenue avec le nom du programme, votre nom pour faire classe :p et éventuellement la version du programme s'il vous arrive de l'améliorer de temps en temps.
Afficher un menu où le joueur pourra choisir de commencer une partie (on se rendra alors à l'étape 4) , de consulter les règles de jeu (dans ce cas, on se rendra à l'étape 3) ou de quitter le jeu (étape 9).
Demander le nombre de joueurs (1 ou 2) en affichant un menu pour que le joueur fasse son choix.
Tirer au sort le joueur qui commencera à jouer.
Afficher les allumettes restantes et demander, tour à tour, à chaque joueur combien d'allumettes il veut retirer (si il n'y à qu'un joueur, faire jouer l'ordinateur) jusqu'à ce qu'il n'en reste plus.
Afficher le résultat de la partie (lequel des joueurs l'emporte).
Demander au joueur s'il veut recommencer une partie sans changer le nombre de joueurs (si c'est le cas, on recommence à partir de l'étape 5, sinon on retourne à l'étape 2) ou s'il veut quitter le jeu (étape 9).
Quitter le jeu en effaçant l'écran.
Le déroulement du programme est maintenant clair, net et précis, et mine de rien on vient de simplifier tout le travail. Comme on dit, y'a plus qu'à ! (j'aurais pu faire un plan beaucoup plus complet en décrivant comment procéder à chaque étape, mais ça aurait été très long et je ne veux pas vous noyer, c'est pour ça que nous le ferons ensemble dans la seconde partie ;) c'est-à-dire maintenant :D ).
Avant tout, je préfère préciser deux choses : la première est que j'expliquerai ce programme de A à Z, si en regardant le plan du programme vous pensez n'avoir aucune idée de comment faire, aucun problème ! Je vous guiderai pas à pas ;) . La seconde : si jamais il y a une fonction que vous n'arrivez pas à trouver, vous pouvez la chercher dans le catalogue où toutes les fonctions sont réunies et classées par ordre alphabétique en appuyant sur les touches 2nd puis 0. Cette fois ci, on est parti !
Commencez donc par créer un nouveau programme que vous appellerez comme bon vous semble (touches prgm, puis deux fois flèche droite, puis enter). Vous pouvez alors commencer à programmer.
On va commencer par la première étape, logique :) . On veut afficher un écran de bienvenue avec du texte mais on doit d'abord s'assurer que rien d'autre ne sera affiché, sinon ça va pas être très beau ^^ . On va donc désactiver l'affichage des axes, puis effacer l'écran (appuyez sur les touches 2nd puis zoom (tout en haut, la touche du milieu) puis amenez le curseur sur "axes off" et appuyez sur enter, ce qui désactivera les axes pour le moment :) ). On efface maintenant l'écran et par la même occasion, le graphique sur lequel des courbes sont peut-être encore affichées.
Vous devez donc normalement à ce stade avoir trois lignes dans votre programme :
AxesOff
ClrHome
ClrDraw
On peut maintenant afficher notre texte d'accueil, pour centrer le texte il faut bidouiller un peu les coordonnées jusqu'à ce que le résultat soit convenable. Pour ma part je procèderai comme ceci :
Text(20,17,"JEU DES ALLUMETTES")
Text(26,35,"PAR NEPH")
On va maintenant utiliser une fonction très pratique : la pause (vous avez dû la voir dans le tuto sur le TI-Basic), elle permet comme son nom l'indique de mettre le programme en pause jusqu'à ce que le joueur appuie sur la touche "enter". Pour utiliser cette fonction, appuyez sur les touches prgm puis 8. Je vous montrerai l'utilité de cette fonction dans quelques instants ;) .
On passe maintenant à l'étape 2, on affiche le menu principal. Juste avant, on va insérer un label (touche prgm puis 9) pour indiquer au programme que cet endroit précis du programme est le menu principal, cela permettra par la suite de revenir au menu principal très facilement, tapez donc :
Lbl 02
On affiche maintenant le menu, pour cela tapez prgm puis alpha (la touche verte) puis de nouveau prgm. Voilà comment utiliser un menu :
Menu("TITRE DU MENU","CHOIX 1",adresse du choix 1,"CHOIX 2",adresse du choix 2)
Les adresses correspondent aux labels, par exemple pour revenir au menu principal, il faudrait mettre :
Menu("QUE FAIRE ?", "MENU PRINCIPAL",02,"QUITTER",adresse pour quitter)
car 02 est le numéro du label que nous avons attribué au menu principal, vous vous rappelez ? (remarque : j'ai mis 02 car c'est le numéro qui correspond à l'étape du menu principal)
Si nous suivons notre plan, nous devons donc taper ceci :
Comme nous n'avons pas encore défini les labels 04, 03 et 09, le programme renverra une erreur, mais vous pouvez vous amusez à mettre 02 à la place de 04 pour tester, le menu principal reviendra donc indéfiniment vers lui même ! Un peu bête mais c'est juste pour tester ^^ .
Au fait, maintenant qu'on a notre menu, essayez donc de supprimer la pause juste avant pour tester ;) utile non ?
On passe maintenant à l'étape 3, il va falloir effacer de nouveau le graphique puis afficher les règles en ayant pris soin de mettre le label 03 avant et enfin, revenir au menu principal avec une pause (au label 02 donc). C'est assez long à taper mais c'est mon jour de bonté, je vous donne le modèle :
Lbl 03
ClrDraw
Text(0,0,"REGLE DU JEU :")
Text(6,0,"ENLEVER ENTRE UNE ET SIX")
Text(12,0,"ALLUMETTES SANS PRENDRE LA")
Text(18,0,"DERNIERE.")
Pause
Goto 02
Reprenons notre programme depuis le début :
AxesOff
ClrHome
ClrDraw
Text(20,17,"JEU DES ALLUMETTES")
Text(26,35,"PAR NEPH")
Pause
Lbl 02
Menu("MENU PRINCIPAL","JOUER",04,"REGLE",03,"QUITTER",09)
Lbl 03
ClrDraw
Text(0,0,"REGLE DU JEU :")
Text(6,0,"ENLEVER ENTRE UNE ET SIX")
Text(12,0,"ALLUMETTES SANS PRENDRE LA")
Text(18,0,"DERNIERE.")
Pause
Goto 02
On passe maintenant à l'étape 4, on affiche un menu pour demander le nombre de joueurs, ce qui donne (on a l'habitude maintenant ;) ) :
Lbl 04
Menu("NOMBRE JOUEURS","UN",41,"DEUX",42)
On stocke ensuite le nombre de joueurs dans la variable J, pour cela, tapez le nombre que vous voulez stocker dans votre variable, puis appuyez sur la touche STO-> (juste au dessus de ON) puis tapez le nom de la variable (une seule lettre).
Lbl 41
1->J
Goto 05
Lbl 42
2->J
Lbl 05
On en est maintenant à l'étape 5, il faut déterminer quel joueur jouera le premier. Pour cela, on stockera 1 ou 0 dans la variable T (comme tour, c'est bien aussi de choisir des noms de variables dont on se rappelle facilement :) ). Si T = 0, c'est le tour du joueur 1 (mon tour), sinon c'est le tour de l'autre.
On génère donc un chiffre aléatoire entre 0 et 1 grâce à la fonction rantInt (à trouver dans le catalogue, 2nd puis 0) qui s'utilise comme ceci :
randInt(0,1)->T
Puis on stocke le nombre total d'allumettes dans la variable A, ici, 36.
36->A
Enfin, j'ai décidé d'afficher les 36 allumettes (qui seront en fait des i majuscules) sur 3 lignes (on ne peut pas les afficher sur une seule ligne) avec 12 allumettes sur chaque ligne. On va donc créer une liste qui contiendra trois nombres : le premier sera le nombre d'allumettes sur la première ligne, le deuxième représentera la seconde ligne et le dernier comptera les allumettes sur la dernière ligne. Pour créer cette liste tapez ceci :
{12,12,12}->L1
Pour le L1, tapez 2nd puis 1, pour l'accolade de gauche, tapez 2nd puis "(", pour celle de droite, tapez 2nd puis ")".
On passe alors à l'étape 6 : le tour de jeu ! Le plus intéressant :) .
Voilà comment cela va se dérouler : premièrement on affiche les allumettes, ensuite on fait jouer les joueurs (je vous montrerai comment réaliser une "IA" extrêmement simplifiée à la fin du tuto)
On va faire une boucle : jusqu'à ce que le nombre d'allumettes soit inférieur à un, on continuera à demander aux joueurs, tour à tour, combien d'allumettes ils veulent retirer. Cela se traduit par la fonction (je devrais dire boucle) Repeat (touches prgm puis 6) sans oublier de mettre un End (prgm puis 7) pour indiquer l'endroit où s'arrête cette boucle.
Repeat A<1 //JUSQU'A ce que A soit plus petit que un (qu'il n'y ai plus d'allumettes donc), on va exécuter les instructions se trouvant dans la boucle (entre le repeat et le end donc :) )
Voici le code qui va permettre d'afficher les allumettes : (pour utiliser For : prgm puis 4)
For(I,1,3)
For(K,1,L1(I))
Output(2I+2,K+2,"I")
End
End
C'est assez compliqué à expliquer pour le moment, surtout si ce n'est que votre premier programme, les personnes un peu plus expérimentées devraient pouvoir comprendre après avoir examiné ce code d'un peu plus près ;) .
Ensuite, voici la manière dont va se dérouler un tour de jeu : si il n'y a qu'un seul joueur (J=1) et que c'est à l'ordinateur de jouer (T=1), alors je dois prendre un chiffre au hasard entre 1 et 6 pour faire jouer l'ordinateur, sinon je dois simplement demander une valeur entre 1 et 6 au joueur, quel qu'il soit, puis changer la variable T (dans les deux cas).
Cela se fait très simplement (explications en dessous du code) :
If J=1 and T=1 //SI il n'y a qu'un seul joueur ET que c'est le tour de l'ordinateur,
Then //ALORS exécuter les instructions suivantes jusqu'au End
RandInt(1,6)->E //on stocke le nombre d'allumettes à Enlever (avec un grand E) qui est un chiffre au hasard entre 1 et 6.
Output(1,1,"LORDINATEUR EN")
Output(2,1,"ENLEVE :")
Output(2,10,E) //on affiche le nombre d'allumettes que l'ordinateur enlève pour que le joueur puisse le savoir
Pause //ne pas oublier la pause ;) .
Else //SINON (si c'est mon tour de jouer OU qu'il y a deux joueurs) on va demander une valeur a un joueur.
Repeat E<7 and E>0 //JUSQU'A ce que le nombre d'allumettes à enlever soit compris entre 1 et 6 (on ne veut pas qu'un joueur puisse enlever plus de 6 allumettes, mais il ne peut pas non plus en enlever 0 ou pire, un chiffre négatif !)
Output(2,1,"JOUEUR")
Output(2,8,T+1) //on affiche le numéro du joueur (j'ai mis T+1 pour afficher joueur 1 et 2 et non joueur 0 et 1)
Input "NBR A ENLEVER",E //On demande au joueur le nombre d'allumettes à enlever puis on stocke la valeur dans E.
Int(E)->E //ici, la fonction int supprime la partie décimale de E, au cas où le joueur ai entré 1,5 par exemple, car on ne peut pas retirer 1,5 allumettes !
End //fin du Repeat
End //fin du If
ClrHome //on efface l'écran un très court instant pour que "NBR A ENLEVER" s'affiche toujours sur la première ligne (faites un essai sans ce ClrHome pour voir ;) ).
Not(T)->T //on change le tour
L1(1)-E->L1(1) //On supprime les allumettes de la première ligne (le 1er terme de L1 correspondant aux allumettes sur la 1ère ligne)
If L1(1)<0 //SI il n'y a plus assez d'allumettes sur la première ligne
Then //ALORS exécuter les instructions jusqu'au End
L1(2)+L1(1)->L1(2) //on supprime les allumettes manquantes sur la deuxième ligne (qui correspond à L1(2)) la ligne de code à l'air compliquée, mais analysez la bien, ce n'est qu'une petite gymnastique d'esprit ! :D
0->L1(1) //on remet le compteur de la première ligne à zéro (il ne peut pas y avoir un nombre d'allumettes négatif sur une ligne !)
If L1(2)<0 //SI il n'y a plus d'allumettes sur la deuxième ligne non plus
Then //ALORS
L1(3)+L1(2)->L1(3) //on les supprime sur la dernière ligne !
0->L1(2) //on remet le compteur de la deuxième ligne à zéro
End //Fin du deuxième if
End //Fin du premier if
L1(1)+L1(2)+L1(3)->A //On stocke le nouveau nombre d'allumettes dans A (c'est la somme du nombre d'allumettes sur chaque ligne !)
End //fin du repeat
Vous noterez la présence de la fonction not, son fonctionnement est simple : elle renvoi l'inverse logique de la valeur qu'on lui donne. Je m'explique : si on lui envoie une valeur égale à zéro, elle renverra un, sinon, pour n'importe quelle autre valeur (même négative), elle renverra zéro ! Très pratique dans notre cas car elle sert à "inverser" le tour de jeu ;) . Une petite astuce que j'ai trouvée et que j'utilise assez souvent.
Et voilà :D . Tout ce code ne devrait pas vous poser de problème si vous avez lu le tuto sur le Ti-Basic et si vous réfléchissez un peu ;) . N'hésitez pas à prendre un peu de repos quand même, allez vous détendre, parce que mine de rien, c'est déjà du costaud tout ça !
On passe maintenant à l'étape 7 : afficher le vainqueur, mais comment faire ? Une fois de plus, ce n'est pas difficile : le dernier joueur à avoir joué est, logiquement, celui qui a pris la dernière allumette, c'est donc aussi celui qui a perdu ! Or à la fin de son tour de jeu, la variable T à été inversée, elle contient donc le tour du vainqueur, vous me suivez ? Par contre, il ne faut pas oublier que si il n'y a qu'un seul joueur, il faut afficher que le vainqueur est l'ordinateur !
ClrHome
Output(3,4,"VAINQUEUR:")
If J=1 and T=1 //SI il n'y a qu'un seul joueur ET que c'est le tour de l'ordinateur (et donc, qu'il a gagné)
Then
Output(4,4,"ORDINATEUR")
Else //SINON afficher le numéro du joueur qui a perdu.
Output(4,5,"JOUEUR")
Output(4,12,T+1)
End
Pause
ClrHome
Et voilà :D , simple comme bonjour n'est-ce pas ? Etape 8 : demander au joueur s'il veut recommencer ou non, ou s'il veut quitter, un fois de plus, voilà un menu :
Et voilà, il ne reste plus qu'à mettre en place le label 09 pour quitter (étape 9 donc), on efface l'écran et le graphique pour éviter d'être encombré par la suite.
Lbl 09
ClrHome
ClrDraw
Lorsque la machine ne rencontre plus d'instructions à exécuter, elle arrête automatiquement le programme ! Voilà donc notre programme terminé :
AxesOff
ClrHome
ClrDraw
Text(20,17,"JEU DES ALLUMETTES")
Text(26,35,"PAR NEPH")
Pause
Lbl 02
Menu("MENU PRINCIPAL","JOUER",04,"REGLE",03,"QUITTER",09)
Lbl 03
ClrDraw
Text(0,0,"REGLE DU JEU :")
Text(6,0,"ENLEVER ENTRE UNE ET SIX")
Text(12,0,"ALLUMETTES SANS PRENDRE LA")
Text(18,0,"DERNIERE.")
Pause
Goto 02
Lbl 04
Menu("NOMBRE JOUEURS","UN",41,"DEUX",42)
Lbl 41
1->J
Goto 05
Lbl 42
2->J
Lbl 05
randInt(0,1)->T
36->A
{12,12,12}->L1
Repeat A<1
For(I,1,3)
For(K,1,L1(I))
Output(2I+2,K+2,"I")
End
End
If J=1 and T=1
Then
RandInt(1,6)->E
Output(1,1,"LORDINATEUR EN")
Output(2,1,"ENLEVE :")
Output(2,10,E)
Pause
Else
Repeat E<7 and E>0
Output(2,1,"JOUEUR")
Output(2,8,T+1)
Input "NBR A ENLEVER",E
End
End
ClrHome
Not(T)->T
L1(1)-E->L1(1)
If L1(1)<0
Then
L1(2)+L1(1)->L1(2)
0->L1(1)
If L1(2)<0
Then
L1(3)+L1(2)->L1(3)
0->L1(2)
End
End
L1(1)+L1(2)+L1(3)->A
End
Output(3,4,"VAINQUEUR:")
If J=1 and T=1
Then
Output(4,4,"ORDINATEUR")
Else
Output(4,5,"JOUEUR")
Output(4,12,T+1)
End
Pause
ClrHome
Menu("RECOMMENCER?","OUI",05,"NON",02,"QUITTER",09)
Lbl 09
ClrHome
ClrDraw
Pour terminer, j'aimerai que nous rajoutions une "IA" à l'ordinateur, car, par exemple, s'il ne reste que deux allumettes, comme on tire un chiffre au hasard entre un et six, il est fort probable qu'il prenne la dernière allumette alors qu'il n'aurait pas du ! Notre programme tel quel ne présente donc pas un grand intérêt en mode un joueur, l'ordinateur étant vraiment simple à battre.
Pour éviter cela, nous (ou plutôt vous :D ) allons programmer quelques lignes afin que, s'il reste 7 allumettes ou moins, l'ordinateur, plutôt que de prendre un chiffre aléatoire, enlève un nombre précis d'allumettes afin qu'il n'en reste plus qu'une ;) . A vous de jouer, essayez de réfléchir à ça sans regarder la solution (qui ne tient qu'en quelques lignes !)
If A>1 and A<8
Then
A-1->E
Else
RantInt(1,6)->E
End
Voilà ma solution, il en existe d'autres évidemment (un même programme peut être écrit de mille façons différentes ;) ). On pourrait pousser l'IA un peu plus loin, voir même rendre l'ordinateur imbattable ce qui n'est pas si compliqué qu'il n'y paraît en réalité, il suffit de connaître le truc, mais pour ça je vous laisse vous creuser un peu la tête :p .
Et voilà, c'est terminé, j'avoue que ce tuto aura été beaucoup plus long que je ne le pensais à la base, et encore j'ai supprimé pas mal de morceaux (le plus possible pour ne pas trop vous encombrer ^^).
J'espère que vous avez compris et que cela vous donnera envie d'améliorer le programme ou mieux : de créer les vôtres ! Rappelez vous qu'aucun programme n'est parfait (même pas les miens :p ) et qu'il est toujours possible de les améliorer ;) .
Si vous avez des questions, réclamations ou que vous n'arrivez pas à comprendre une partie du tuto, n'hésitez pas à m'écrire, je serais enchanté de vous aider ;) .