TI Codes
Pour aller plus loin, mettre en pratique les connaissances de bases et programmer des jeux.
Devinettes
Écrivons un simple jeu de devinettes
Le jeu de devinettes inclut plusieurs composants :
- La variable N et nbrAléatEnt() utilisés pour choisir le nombre à deviner.
- Une boucle Repeat qui va sans cesse demander un nombre jusqu’à ce que le jouer trouve le bon.
- La commande Prompt utilisée pour obtenir une supposition du joueur.
- La structure conditionnelle If et l’instruction Disp utilisées pour dire au joueur si sa réponse est trop grande ou trop petite.
- La variable M et l’instruction Disp utilisées pour suivre et rapporter le nombre de suppositions faites par le joueur.
étape 1
étape 2
Comment fonctionne le jeu de devinettes
Le diagramme ci-contre est un organi-gramme montrant comment fonctionne le programme. Si vous n’avez pas vu d’organigramme auparavant, vous le lirez en suivant les flèches autour du diagramme, en commençant à Début et en finissant à Stop. Si vous passez une minute pour comparer ce diagramme et le code de prgmDEVINE, vous verrez que chaque bloc correspond à une à trois ligne(s) du programme
étape 3
:nbrAléatEnt(1,50)→N
Génére un entier aléatoire entre 1 et 50, et le stocke dans la variable N. Chaque fois que le programme donne une nouvelle devinette au joueur, il le comparera à N pour tester si c’est correct.
:0→M
Stocke le nombre d’essais dans la variable M. Chaque fois que le joueur fait une autre supposition, le programme ajoutera 1 à M, puis affiche le contenu de M à la fin du programme.
2 :Repeat G=N
Répéte le code, entre cette commande Repeat et la commande End correspondante, jusqu’à ce que G=N. Dans ce programme, G est la conjecture faite par l’utilisateur, et N est le nombre à trouver, ainsi la boucle se termine quand la conjecture est égale au nombre que le joueur essaie de deviner. Une bizarrerie de Repeat : est qu’il ne teste la condition (G=N) qu’après avoir effectué une boucle complète. Par concéquent, nous n’avons pas à initialliser G en y stockant une valeur comme 0, par exemple, avant le démarrage de la boucle. Si nous avions utilisé une boucle While, nous aurions dû initialiser G, car While teste la condition avant de lancer le démarrage de la boucle.
:Prompt G
Demande au joueur une valeur pour G, puis stocke le nombre que le joueur tape dans la variable G.
étape 4
:Disp "TROP GRAND"
Si la réponse G est plus grande que le nombre à deviner N, on affiche TROP GRAND de façon à ce que le joueur sache qu’il doit donner un nombre plus grand ou plus petit. La commande If exécutera la ligne suivante du programme si la condition (G>N) est vraie ; sinon, elle la sautera.
:If G :Disp "TROP PETIT"
De façon similaire, si la réponse G est plus petite que le nombre à deviner N, on affiche TROP PETIT. If G=N, la boucle ne sera pas encore terminée, mais la commande Disp ne sera pas non plus exécutée, car G n’est ni plus grand, ni plus petit que N.
:M+1→M
Ajoute 1 au nombre d’essais réalisés.
:End
Termine la boucle et teste la condition Repeat. Si la condition G=N est fausse, on exécute de nouveau la boucle, en commençant à Repeat. Si elle est vraie, le programme continue avec le code suivant le End.
:Disp "CORRECT APRES :"
:Disp M
:Disp "ESSAIS"
Affiche trois lignes, incluant le nombre d’essais effectués. Vous pouvez optimiser ceci à l’aide d’un Disp sur une seule ligne avec des virgules.
étape 5
Aller plus loin : Développez votre jeu
- Laisser le joueur choisir entre quelles limites le nombre à deviner sera pris. Le jeu dans cette leçon tire un nombre entre 1 et 50.
- Afficher entre quelles valeurs le joueur devra choisir ses réponses, ici entre 1 et 50.
- Garder trace du meilleur score (le plus petit nombre d’essais effectués). Vous pouvez garder trace également d’autres statistiques, comme la moyenne du nombre d’essais ou le plus mauvais score (le plus grand nombre d’essais effectués). Pour stocker des informations dans plus de variable que le nombre des variables numériques A-Z, jetez un œil à l'information sur les listes personnalisées.
- Utiliser Input à la place de Prompt pour demander les propositions.
- Trouver une façon d’effacer l’écran avant que le jeu ne commence.
Boucles événementielles
Le programme que nous allons créer dans cette leçon est assez court, mais rassemble un certain nombre de concepts de programmation importants.
Nous allons construire un programme autour d'une boucle événementielle : une section de code est exécutée de façon répétitive, en attente d’événements et réagissant à ces derniers.
Dans ce programme, les événements que nous allons rechercher consistent en l'appui sur des touches, notre programme répondra à ces événements en déplaçant une lettre dans l'écran de calcul de la calculatrice.
Les Boucles événementielles dans les programmes informatiques peuvent attendre une heure ou une date, un clic de souris, l’appui sur une touche du clavier, ou même l'arrivée de paquets venant du réseau.
étape 1
Boucles événementielles et getKey
Le schéma ci-contre montre la structure de base d'un programme fondé sur des boucles événementielles. Il exécute le code pour mettre en place la boucle, comme par exemple l’initialisation de variables, puis répète la boucle événementielle jusqu’à ce qu’une condition d’échappement se produise.
Il existe trois composantes majeures dans une boucle événementielle :
- Une condition d’échappement qui définie quand la boucle événementielle s’arrête. Dans un programme informatique, une condition d’échappement peut être quelque chose comme appuyer sur la touche [ESC]. Dans notre programme, nous allons vérifier la touche ‘, et notre condition de sortie pourrait être formulée comme “fin de la boucle événementielle si la touche ‘ est enfoncée”.
- Code non-événement. Dans ce programme, nous n’aurons pas de code non-événement. Cependant, dans d'autres programmes, c’est le code qui est exécuté indépendamment du fait que des événements se produisent ou non.
- Vérification des (et réaction aux) événements. Dans ce programme, nos événements sont des pressions de touches. Si nous voulons vérifier et réagir aux pressions de touches, nous devons être en mesure d'exécuter ou de sauter des sections de code suivant qu’il y a eu pression sur une touche ou non.
étape 2
Les instructions Conditionnelles vous permettent de contrôler quelles sections de code sont exécutées ou non. Les instructions conditionnelles consistent en une condition qui peut s’évaluer à vrai ou faux, et le code qui est exécuté si la condition est vraie. Les conditions peuvent ressembler à cela : If A>1 ou If K=24 ou If K=25 et B>1, sur votre calculatrice. Heureusement, elles font exactement ce à quoi elles ressemblent : la première est vraie si la variable A>1, la seconde est vraie si K=25 et la troisième est vraie si à la fois K=25 et B>1 sont vraies. La forme la plus simple de structure conditionnelle sur votre calculatrice est constituée par la condition sur une seule ligne, suivie directement par une deuxième ligne de code qui est exécutée si la condition est vraie ou ignorée si la condition est fausse. Vous pouvez aussi créer des structures conditionnelles plus complexes en utilisant If/Then/End et If/Then/Else/End.
étape 3
Explorons le programme MOVECAR. Le programme MOVECAR est un des exemples le plus simple possible de programmation événementielle : sans cesse être à l’écoute des événements “appui sur une touche” et agir sur eux. L’organigramme ci-contre représente le programme MOVECAR. La boucle événementielle va de “Redessine M” à “Teste pression touches” puis revient à “Redessine M”. La condition d’échappement dont nous avons discuté plus tôt était la condition pour quitter la boucle événementielle ; ici, vous pouvez voir que la seule façon de quitter la boucle est d’appuyer sur la touche ‘.
Notez que si vous utilisez une calculatrice TI-8x, les seules différences sont dans les valeurs utilisées pour les bords de l’écran de calcul et le point de départ, ceci étant dû aux différences de taille de l’écran de calcul des calculatrices.
étape 4
:13→A
:5→B
Initialisez les coordonnées de la lettre qui va être dessinée. Nous n’utilisons pas les variables X et Y, car le système d’exploitation de la calculatrice modifie parfois la variable Y si vous utilisez des commandes de l’écran graphique. Dans ce programme, A contient l’abscisse et B l’ordonnée. Colonne 13, ligne 5 correspond à peu près au centre de l’écran de calcul d’une calculatrice couleur.
:EffÉcran
Efface l’écran de calcul.
:Repeat K=45
Répète tout le code entre Repeat et End (la boucle événementielle) jusqu’à ce que la variable K soit égale à 45 (code de la touche ‘).
:Output(B,A,"M”)
Dessine la lettre M à la ligne B, colonne A dans l’écran de calcul. S’il y a déjà un M sur l’écran aux mêmes coordonnées, il est simplement dessiné dessus, ainsi l’écran ne change pas.
:getKey→K
Obtient le code de toute touche enfoncée depuis le dernier appel de getKey, et le stocke dans la variable K. Ceci revient immédiatement, au lieu d’attendre la pression sur une touche : si aucune touche n’est enfoncée, 0 est stocké dans K.
étape 5
Si une touche a été enfoncée, nous devons effacer la lettre déjà présente à l’écran, parce que nous pourrions avoir à la déplacer. Si nous ne l’effaçons pas, nous laisserions une traînée de M à l’écran.
:Output(B,A,"_”)
Dessiner un espace sur le M qui est à l’écran, en réalité l’efface. Cette ligne de code est seulement exécutée si K n’est pas égal à zéro.
:If K=24 et A>1
:A-1→A
Gère la touche directionnelle gauche, |, code 24. Si la touche directionnelle gauche a été enfoncée, nous devons soustraire 1 de l’abscisse afin que M se déplace d’un espace vers la gauche. Cependant, nous ne voulons pas déplacer le M au-delà du bord de l'écran. Par conséquent, nous soustrayons seulement 1 à A et stockons de nouveau le résultat dans A, si à la fois K=24 (la touche directionnelle gauche a été enfoncée) et A>1 (le M n’était pas déjà sur le bord gauche de l’écran).
étape 6
:A+1→A
:If K=25 et B>1
:B-1→B
:If K=34 et B<>
:B+1→B
Gère les touches directionnelles droite, haut et bas. Chaque instruction conditionnelle contrôle, si à la fois une touche directionnelle a été enfoncée, et si la lettre n’est pas déjà au bord correspondant de l’écran.
:End
Revient à la commande Repeat, sauf si K=45. Si K est égale à 45, la boucle se terminera, et comme c’est la dernière ligne du programme, le programme prendra fin ainsi.
étape 7
Avec ce type de programmation événementielle simple, qui surveille et réagit à la pression de touches, vous pouvez construire de nombreux programmes ludiques et en particulier des jeux.
- Une façon facile pour démarrer serait de faire autre chose que le déplacement d’un M à l’écran. Peut-être une lettre différente ? Ou un groupe de lettres dans une forme ?
- Gérer les mouvements diagonaux de telle sorte que la lettre puisse se déplacer dans 8 directions au lieu de seulement 4. getKey ne pouvant enregistrer plusieurs touches directionnelles en même temps, vous pouvez utiliser les touches 1–9 à la place des touches directionnelles ( Á pour bas, ¬ pour haut-gauche, etc.).
- Si vous êtes habitué à dessiner du texte sur l’écran graphique, essayez de modifier ce programme afin qu’il agisse dans l’écran graphique. Quelles commandes avez-vous besoin de changer, et quelles sont celles qui restent les mêmes ? Quelles sont les nouvelles limites à utiliser pour empêcher le texte de sortir de l’écran ?
- Essayez de changer le programme MOVECAR en un jeu de tir dans l’espace : le M peut devenir votre vaisseau spatial, et vous essayez de tirer sur des astéroïdes avant qu’ils ne vous atteignent. Comment pouvez-vous implémenter une arme, garder une trace de l'endroit où se trouvent les astéroïdes et gérer le score ?
Serpent
Créez le programme Serpent sur votre calculatrice sous le nom prgmSERPENT. Si vous avez une calculatrice avec écran couleur comme la TI-83 Premium CE, vous pouvez le rentrer exactement comme ce qui est montré. Pour une calculatrice TI-8x, vous devez prendre en compte le fait que l’écran de calcul est plus petit.
étape 1
:EffÉcran
Efface l’écran de calcul.
13→A
:5→B
:10→X
:1→P
:26→D
Initialise toutes les variables utilisées :
- A est l’abscisse de la tête du serpent, et B son ordon-née. Ligne 5, colonne 13 correspond à peu près au centre de l’écran de calcul de la TI-83 Premium CE.
- X est la longueur du serpent, ici, 10 anneaux. Si vous vouliez faire un vrai jeu du serpent, vous devriez commencer avec une petite longueur X, et l'augmenter au fur et à mesure que le serpent mange de la nourriture.
- P est un pointeur vers l'élément terminant la queue du serpent. L1(P) est l’ordonnée de la queue du serpent, et L2(P) son abscisse. Comme le serpent se déplace, P se déplace aussi, de sorte qu'il pointe toujours sur la fin du serpent (sans avoir à faire avancer les données dans L1 et L2).
- D est la direction vers laquelle le serpent se dirige. Pour réutiliser le code que vous avez vu auparavant, nous utilisons les codes des touches pour haut, bas, gauche et droite (25, 34, 24 et 26, respectivement) pour représenter la direction vers laquelle le serpent se dirige.
:X→dim(L2)
Créez deux listes, toutes les deux de X éléments de long, servant de mémoires tampons circulaires pour les coordon-nées des anneaux du serpent.
étape 2
:Fill(A,L2)
Remplissez les deux listes avec les coordonnées de départ. De cette façon, les 10 anneaux du serpent commenceront en un seul endroit de l’écran de calcul, et au démarrage du jeu, le serpent semblera sortir de cet endroit pour atteindre sa pleine taille. Dessiner le serpent au départ à sa pleine longueur serait plus compliqué.
:Repeat K=45
Comme dans la Leçon 2, répéter la boucle événementielle principale jusqu’à ce que la touche ‘ soit enfoncée.
:Output(L1(P),L2(P),"_”)
Effacez la queue du serpent. Car nous utilisons des mémoires tampons circulaires, nous changeons P de façon à ce qu’il pointe toujours vers les éléments de L1 et L2 actualisant la queue du serpent. L1(P) est l’ordonnée (ligne) du dernier anneau de la queue et L2(P) son abscisse (colonne).
:Output(B,A,"0")
Redessine la tête. A et B contiennent toujours les coordon-nées de la tête du serpent, "0" juste pour bien ressembler à un anneau de serpent... Vous pourriez utiliser n’importe quel autre caractère à la place.
:B→L1(P)
:A→L2(P)
Stocke les coordonnées courantes de la tête dans les mémoi-res tampons. Comme P+1 pointera vers la queue à la prochaine itération, P pointera vers la tête, ainsi nous stockons ses coordonnées par-dessus les anciennes coordonnées de la queue dans P.
étape 3
Met P à jour pour pointer vers le prochain élément des listes. Si P est inférieur à X, alors P=X est fausse (0), et ceci se sim-plifie en P+1→P. Si P pointe déjà vers les derniers éléments de la mémoire tampon, ce qui signifie P=X, alors P=X est vraie (1), ceci se simplifie en P+1-X→P, ou X+1-X→P, soit 1→P. Ainsi, quand P atteint la fin de la liste, il retourne au début.
:getKey→K
:If max(K={24,25,26,34})
:K→D
Gère les pressions sur les touches. Habituellement, nous stockons le code de la touche enfoncée dans K, de sorte que la condition Repeat (K=45) peut dire si ‘ a été enfoncée. L’instruction conditionnelle est une abréviation de “If K=24 ou K=25 ou K=26 ou K=34”. K={24,25,26,34} produit une liste de 4 éléments, {K=24,K=25,K=26,K=34} qui donne une liste de 1 et de 0. La commande max() donne la plus grande valeur de la liste, ainsi si K est égale à l’un de ces quatre nombres, il y aura un 1 dans la liste résultante, le maximum sera 1. Si K n’est égale à aucun de ces quatre codes, la liste sera remplie avec des 0, et le maximum de la liste sera 0. Donc, la condition ne sera vraie que si K est égale à l’un de ces quatre codes de touche. De plus, si K contient le code d’une touche directionnelle, D est mise à jour pour contenir une nouvelle direction vers où va aller le serpent.
étape 4
:B+(D=34)-(D=25)→B
Utilisez la variable de direction D pour mettre à jour les coordonnées de la tête. Si D=26 ou D=24, alors la tête du serpent se déplace horizontalement. Mettez à jour A (l’abscisse) en conséquence. Essayez d’introduire D=26 et D=24 dans la première ligne pour voir comment cela fonctionne. La seconde ligne met à jour B, l’ordonnée de la tête, si D=34 ou D=25, ce qui signifie que la tête se déplace vers le haut ou vers le bas.
:A+26((A=0)-(A=27))→A
:B+10((B=0)-(B=11))→B
Les deux précédentes lignes peuvent faire sortir le serpent des limites de l’écran. Si vous essayez de dessiner un caractère en dehors des limites de l’écran, le programme se terminera avec une ERREUR DE DOMAINE, ainsi nous devons le modifier. Ces deux lignes font passer la tête d’un bord à l’autre de l’écran. Par exemple, si elle atteint le haut de l’écran, elle réapparaîtra en bas.
:End
On revient à la commande Repeat, à moins que K=45. Si K=45, la boucle se termine, et comme c’est la dernière ligne du programme, le programme se termine aussi.
étape 5
Le programme SERPENT que nous venons de voir contient tous les éléments dont vous avez besoin pour commencer de construire le jeu du “Serpent”. Les trois morceaux les plus importants qui manquent sont : (1) un serpent qui grandit, (2) le score et (3) des aliments pour manger. Voici ce que vous pourriez faire pour construire le jeu complet du "Serpent" à partir de cette version de base :
- En premier, vous aurez besoin d’une seconde variable pour gérer le pointeur de tête. Dans cette version, nous avons utilisé P en même temps comme pointeur de tête et de queue, car la mémoire tampon circulaire était toujours complètement pleine.
- Puis, vous aurez besoin d’avoir des mémoires tampons circulaires plus grandes que la taille de départ du serpent, car le serpent devra être en mesure de croître. Ceci vous mènera à des décisions de conception intéressantes : devrez-vous commencer avec des listes aussi grandes que la taille maximale que pourrait atteindre le serpent ? Ou devrez-vous augmenter la taille des listes quand la taille du serpent risque de devenir trop grande pour les mémoires tampons ?
- Puis, vous aurez besoin de nourriture pour faire manger le serpent. Comment allez-vous vous assurer que vous ne mettez pas la nourriture sur le serpent ? Certaines approches permettent de stocker le contenu de l'écran de calcul dans une matrice, de sorte que vous pouvez facilement tester quels points de l'écran de calcul sont occupés.
- Vous aurez besoin de détecter si le serpent est sur le point (ou vient) de manger la nourriture, de sorte que vous pouvez augmenter le score et la longueur du serpent, puis placer un nouveau morceau de nourriture.
- Vous pouvez aller encore plus loin et ajouter des choses comme des murs, des niveaux de formes différentes. Si vous faites cela, vous devrez envisager sérieusement l'approche matricielle afin de détecter facilement quand le serpent rencontre un mur (ou sa propre queue).