Nous allons voir comment faire pour réaliser diverses choses
pratiques et découvrerons pas mal de petites astuces bien pratiques...
Ce dossier s'étoffera au fur et à mesure que des astuces seront découverts.
Sauver des records et autres paramètres de façon permanente :
- Les variables ne peuvent garder un record ou les données de vos programmes
très longtemps car, un jour ou l'autre (et plutôt un jour que l'autre), un programme
l'utilisera invalidant ainsi vos données! Pour éviter cela, il faut utiliser
une liste. Attention : les listes L1 à L6 sont souvent utilisées par des programmes, alors créez-en une
autre : LREC par exemple. Mais il est plus conseillé de
créer une liste avec les trois premiers caractères du programme (vous pouvez
mettre jusqu'à cinq caractères) pour éviter qu'un autre programme utilise votre
liste à nom "générique" (de cette façon, LREC n'est pas un bon choix car tout le monde peut y penser).
- Au tout dabut duprogramme, tapez 1->dim(LREC) puis validez.
Ainsi, si la liste n'existe pas elle sera créée (vide) et si elle existe, elle
sera conservée (avec ses données / records).
Les commandes dim( et L se trouvent dans le menu [2nd] [LIST] [>] puis [3]
ou [B].
Le 1 représente le nombre de lignes de la liste
(si vous avez 5 modes de jeux avec chacun leur records alors il faudra créer
une liste de 5 cases)
- Vous y accéderez pour savoir si les points de la partie sont supérieurs à
celui du record ou pour afficher ce record. Pour cela faites ainsi : LREC(x)->A ou Disp LREC(x) où x est la ligne du record ou
de la donnée à extraire.
- Vous modifierez la ligne de la liste pour stoquer le nouveau record s'il est
battu : A->LREC(x)
Exemple (admettons que vous avez perdu et que P contient vos points) :
:LSNAKE(2)->R
:Disp "RECORD :",R
:If P>R:Then
:P->LSNAKE(2)
:Disp "RECORD BATTU"
:End
Sauvegarde de données dans une liste dont la dimension est indeterminée :
Le meilleur exemple pour illustrer cette nouvelle fonction non-documentée du
mode d'emploi est l'utilisation d'une liste pour stoquer un mode de jeu qui
peut contenir un nombre variable de cases. Hors, ce mode est facultatif (la
liste pesant beaucoup en mémoire, le joueur peut choisir de supprimer cette
liste et de ne pas jouer à ce mode) mais contient le record de ce mode dans
sa première case et il faut l'afficher dans le menu principal.
Comment savoir si ce niveau existe ou pas? Car, si elle n'existe pas, le programme
plantera en essayant d'afficher le record.
Ici, impossible de faire comme précédemment avec dim( car la liste pourrait être tronquée ou agrandie.
La solution est simple mais il fallait la connaître :
- En début de programme, entrez ceci :
:"->LMODE
Ca paraît idiot et on croirait qu'une chaine vide sera stoquée dans la liste
MODE...
Mais non : si la liste existe elle reste telle qu'elle et si elle n'existe pas
elle est créée avec une dimention de 0.
Ainsi, quoi qu'il arrive, la liste existe après l'appel de cette méthode et
on peut la manier avec dim( comme ceci :
:"->LMODE Si la liste n'existe pas elle est créée avec une dimention de
0
:0->R Mise à zéro du record, il n'existe pas
:If dim(LMODE Si la liste existait avant...
:LMODE(1->R ...Mise à jour du record
:Disp "RECORD MODE :",R
Si vous voulez un exemple concret, téléchargez mon jeu SNAKE 3010 qui illustre
bien cette uilisation.
Un autre moyen de sauvegarder : rand :
Stoquez un nombre dans rand et faites une liste
de nombres "aléatoires".
Restoquez ce chiffre dans rand et refaite une liste.
Vous remarquerez que les liste des chiffres pseudo-aléatoires sont les même.
Ainsi, pour éviter de "gâcher" une liste entière ou une image pour
stoquer les résultats, vous pouvez ne stoquer que le nombre qui devra être donné
à rand.
Exemple :
:ClrDraw Efface l'écran graphique
:rand->N Valeur aléatoire pour initialiser rand
:N->rand Initialisation de rand avec le chiffre
tiré au hazard
:... Ici, routine pour afficher des points (presque)
aléatoirement
:... Jeu en lui même, quel qu'il soit
:... Maintenant passons au chargement du jeu
:ClrDraw Efface l'écran graphique
pour charger
:N->rand Initialise rand avec le même nombre
que tout à l'heure...
:... Ici, routine pour afficher les points qui
seront les mêmes que les premiers :
:... La partie et est rechargée : vous pouvez continuer
à jouer
Sous programmes :
- Quand vous avez un programme qui demande de faire à plusieurs reprises
une série de calculs, faites des sous-programmes.
- Je vous conseille de les commencer par un Z, puis de mettre deux ou trois
lettre de votre programme principal et ensuite le nom de la fonction (exemple
: prgmSNAKE est le programme principale, prgmZSNKMOVE est l'un de ses sous programmes).
- Si votre sous-programme doit avoir des paramètres, pensez à
Ans : ainsi vous n'utiliserez pas beacoup de variables.
- Si votre fonction a plusieurs paramètres, vous povez les stoquer dans
une liste.
Pseudo-fonctions et librairies :
- Il est plus pratique de rassembler plusieurs fonctions dans un sous programme.
Dans ce cas, utilisez Ans pour savoir laquelle des fonctions à exécuter.
Exemple : 1:prgmZFUNC lance une
routine pour charger, 2:prgmZFUNC
sauvegarde, 3:prgmZFUNC affiche,
etc...
Pour gérer cela dans la librairie, rien de plus simple :
:If Ans=1:Then:
:...
:Return:End
:If Ans=2:Then:
:...
Return:End
Ne pas utiliser de variables dans un sous programme :
Parfois, vous pouvez distribuer vos sous-programmes (ou librairies) pour que
d'autres programmeurs puissent les utiliser sans réinventer la roue.
Mais votre si sous-programme utilise des variables il se peut qu'elles écrasent
celle utilisées dans le programme principal. Vous avez plusieurs choix
pour éviter cela :
- N'utiliser que Ans. Cependant, vous êtes limités à une
seule variable...
- N'utiliser que Ans, sous forme de liste. Exemple :
:{0,0
:{Ans(1),3+2
:{8+.1R,Ans(2
Ce programme ne fait rien mais montre comment utiliser Ans comme liste. Après
chaque calcul, Ans doit toujours contenir la liste des pseudo-variables.
Ainsi, la première ligne initialise les "variables" à
0, la seconde ligne calcul 3+2 dans la seconde "variable". Mais pour
garder la première il faut utiliser Ans(1).
Sinon on la perdrait.
Ce système est fastidieux et inapplicable dans certains cas comme pour
les boucles For().
- Dernier choix : sauvegarder les variables qui vont être utilisées,
les utiliser, puis restaurer leur valeurs. Comment les sauvegarder ? Et bien
dans une liste, pardis ! Exemple, ce programme utilise les variables A, B et
C : il les sauvegarde donc avant tout calcul puis les restaure :
:{A,B,C->LTMP
:12+2pi->A
:A+53pi->B
:A/B->C
:Disp A:Disp B:Pause C
:LTMP(1->A
:LTMP(2->B
:LTMP(3->C
Pseudo-calcul formel :
- Dès fois il peut être interessant de manipuler des nombres sous
forme de caine de caractères, pour donner les détails d'un calcul
par exemple. Malheureusement la transformation variable->chaine n'est pas
possible. Veillez donc à demander les nombres à l'utilisateur
sous forme de chaine car la transformation inverse est, elle, possible. Faites
cela avec Input "NB:",Str1.
- Ensuite vous pourrez manipuler cette chaine et, le moment venu, vous la retransformerez
en nombre via la fonction expr(Str1->A.
- Pour un programme qui donne tous les détails de calculs, affichez-les
sur l'écran graphique.
En effet, l'instruction Text()
permet d'afficher plusieurs paramètres avec une seule instruction Text().
Exemple :
:Text(1,1,"=",2AB²,"+",C,"(",AB-C,")
Configuration graphique :
- Je préconise toujours la configuration garphique suivante : 0->Xmin:94->Xmax:0->Ymin:62->Ymax.
- La raison en est très simple :
L'écran, noté en pixels va de 0 à 94 en X et de 0 à
62 en Y !! Et ce quelle que soit la configuration graphique (normal ce sont
des pixels ! )
Ensuite, il y a la notation en "points" (c'est comme cela que je l'appelle)
: elle, elle utilise la configuration graphique.
Vous devez savoir que la TI dispose des fonction Pt-On(),
Line(), Pxl-Off()
etc...
Pxl-On(), Pxl-Off(),
Pxl-change() et Texte()
utilisent la notation en pixels et le reste la notation en points.
Hors, dans un jeu nous avons souvent besoin des deux notations.
Donc cette configuration graphique permet de convertir très simplement
une notation vers une autre.
Mais ce n'est pas tout : les notations en points sont sous la forme (X,Y) et
celles en pixels sous la forme (Y,X).
Ensuite, Y part du haut en notation pixels et elle part du bas en notation point.
- Donc, pr résumer, avec cette configuration graphique, si vous avez
la coordonnée (X,Y) en points, vous n'avez juste qu'à faire (62-Y,X)
pr avoir celle en pixels, et inversement.
Ce qui fait qu'il n'y a qu'une seule soustraction : on ne perd pas de tmp (qui
est critique pr faire un jeu HYPER rapide) !
- Une autre variante est "0->Xmin:94->Xmax:-62->Ymin:0->Ymax"
: là on passe de (X,Y) à (-Y,X) : c'est plus simple mais il faut
travailler avec des nombres négatifs...
- Je vous propose de choisir l'une des deux configuration et de toujours l'appliquer
: vous dévelloperez plus vite et votre programmes seeront un poil plus
rapide.
Les données en sécurité contre les RAM Cleared
:
- Pour que les données et sauvegardes de vos programmes ne craignent
pas d'être effacées par un simple RAM Cleared, il faut les archiver
avant de quitter le programme. En début de programme il vous suffira
de les désarchiver. S'ils n'étaient pas archivées aucune
erreur ne surviendra.
- Cependant, avec cette solution, le programme plantera lors de la première
exécution vu qu'il essayera de désarchiver une variable qui n'existe
pas.
Plusieurs solutions s'offrent à vous :
- Fournire ces variables avec le pogramme (mais elles peuvent être supprimées
entre temps)
- Créer un programme d'installation qui créera ces variables
- Utiliser une liste qui restera en RAM, exécuter 1->dim(LMALST),
puis tester LMALST(1)
ce qui retourneraet 0 si le programme n'a jamais été exécuté
(dans ce cas créer les variables), 1 dans le cas contraire.
- Utiliser une liste en RAM. Si vous detectez que le programme n'a jamais été
exécuté, demander à l'utilisateur si les données
ont été sauvegardées ou non et là désarchivez-les
ou créez-les.
- Créer une liste temporaire de dimention 1. Si elle contient 0, y stoquer
1 et désarchiver les données. Avertissez l'utilisateur que si
le programme plante il doit redémarrer. Dans ce cas la liste contiendra
1 : créez les données. N'oubliez pas de supprimer la liste temporaire.
C'est le meilleur choix selon moi.
Travailler avec de très grandes chaînes de caractères
:
Contrairement aux listes et aux matrices, les chaines sont de longueur illimitées...
sauf par la mémoire.
Et justement : si vous travaillez avec de très grandes chaines (plus
de 3000 octets, donc près de 3000 caractères) sachez que la variable
Ans recopie toutes vos modifications.
Ce qui fait qu'en ajoutant un simple caractère à une chaine de
4999 octets ce n'est pas 5000 octets qu'il vous faudra en mémoure mais
10000 !!! Simplement parce que Ans recopiera le résultat, c'est à
dire la chaine entière...
Hors, si la dernière action que le programme a effectué a été
de rajouter un nouveau caractère (ou tout autre opération résultant
la chaine entière), Ans ocuppe déjà 5000 octets et vous
risquez fort de finir avec une erreur ERR:MEMORY
!
C'est génant mais en fait vous pouvez éviter ceci de façon
très simple : faire un calcul factice ou stoquer 0 dans Ans !
Ainsi Str0+"A"->Str0
deviendra 0:Str0+"A"->Str0.
Ans contiendra alors 0 lors du boulimique calcul.
Listes liées et initialisation par chaines de caractères
:
- Vous pouvez initialiser une liste avec une chaine de caractères. Cela
permet de lier plusieurs listes entres elles.
Exemple : {1,2,3->L1:"2L1->L2.
L2 vaudra {2,4,6}.
Exécutons {2,2,2->L1.
L2 vaudra alors {4,4,4}.
- Lorsque vous voulez suprimer cette "liaison dynamique", faites simplement
L2->L2.
- Cela permet aussi de demander un nom de liste à l'utilisateur (Input
Str1:Str1->L1). Par contre l'inverse n'est pas possible.
Ou de demander une liste et de la traiter comme chaine de caractère (pour
un pseudo-calcul formel comme vu ci-dessus : une fois que vous avez formaté
la liste sous forme de chaine, stoquez cette chaine dans une liste).
- NOTE : Pour les listes personnalisées, vous n'avez pas besoin d'utiliser
le petit L après
la flèche STO. Exemple : {1,2->B
stoquera la liste {1,2} dans
LB.
Astuces en vrac
Afficher son programme dans MirageOS :
- Au tout début d'un programme, mettez la caractère : (deux-points). Ceci inclura votre programme BASIC dans
MirageOS.
- Mais il est possible d'y adjoindre une descritption à la place de "Basic
Program : NOMDUPRG" en ajoutant tout de suite après les deux points
une chaine de caractères comme ceci :
::"Description
- Si vous utilisez Pause dans
votre programme (pour l'écran d'introduction par exemple), le tout première
serra passé si le programme a été lancé avec [ENTER].
Veillez donc à commencer ainsi tout programme devant apparaître
sous MirageOS :
::"Description
:getKey
Ralentir un jeu ou faire une pause quelques secondes
:
- 69! : Calcul et fait ralentir le jeu durant une
demi seconde. Pour plus de ralentissements alignez ces commandes ("69!:69!"...)
- For(X,1,100:End : Remplacez le 100 par un chiffre
de plus en plus grand pour patienter plus.
- RandBin(100,0 : Patiente 4 secondes. Remplacez
100 par 1000 pour patienter 20 secondes (ATTENTION : Si vous mettez plus ça
s'appelle un virus!)
Ne pas afficher "Done" à la fin d'un programme :
En toute fin de programme, insérez cette ligne :
:Output(1,1,"
Ainsi, la mention Done n'apparaîtra pas.
Pensez aux applications :
Les applications comme Finances, Symbolic et Omnicalc vous donnent acces à de
nouvelles fonctions.
Finances est installé sur toutes le TI-83 plus et contient des fonctions
bien pratiques comme le calcul du nopmbre de jours entre deux dates. Voyez votre
mode d'emplois.
Texte en grande police sur l'écran graphique :
Essayez Text(-1,5,5,"SALUT") et admirez
: vous venez d'écrire en grands caractères sur l'écran graphique!
Cette fonction est non-documentée sur le mode d'emploi.
randInt sur une autre calculatrice :
Si vous voulez transformer un programme contenant la commande RandInt( pour une TI qui ne la possède pas remplacez-la
par celle-ci : int((Sup-Inf+1)*rand+Inf)
ou, pour un nombre dont Inf = 1 : int(Sup*rand+1)
ClrDraw bien plus instantané :
Lorsque vous configurez l'écran graphique, ajoutez cette ligne : 0->Xscl:0->Yscl
. Ainsi, lorsque vous appelerez ClrDraw, cette commande
sera 50% plus rapide! Pratique pour accélérer des pseudo-vidéo faites d'images
séparrées par un effacement de l'écran.
Protéger / Déprotéger ses programmes facilement :
Pour ceci, téléchargez CalcSys (Télécharger / Application) et lisez le tutoriel
de cette application pour savoir comment faire ceci directement sur la calculatrice
: vous gagnerez ainsi beaucoup de temps.
Les minuscules :
Elles sont jolies mais prennent de la place : deux octets par minuscules eu
lieu de un pour une majuscule.
En plus, si quelqu'un n'a pas le câle TI-PC il devra être obligé
de reopier votre programme.
Et le TI-Graph Link ne supporte pas les minuscules : il ne pourra donc pas.
Commenter ses programmes :
Le TI-BASIC 83+ ne permet pas d'insérer des commentaires.
Bien que prennant de la place "pour rien", ceci est parfois utilie
pour qu'une autre personne s'y retrouve... ou pour que vous vous y retrouviez
après être parti en vacances :-)
- La meilleur solution pour insérer des pseudo-commentaires est de les
insérer sous forme de chaine de caractères, sans les stoquer.
Exemple :
:"INI
:13->A:15->B
:"JEU
:Repeat 0
:getKey->K
:Ans->A
:"SAUVEGARDE
:"LA TOUCHE PR
:"UTILISER +
:"TARD
:If K=25:1->D
Le seul problème, mis à part le gonflement en taille du programme,
est que cela stoque la chaine dans Ans : vous perdrez ce qui est stoqué
dans cette variable.
- Ce système permet aussi d'invalider certaines lignes durant quelques
temps.
Par exemple, si vous n'avez pas besoin d'une certaine partie de code, au lieu
de la supprimer puis de la retapper plus tard, mettez juste une guillemet en
début de ligne et supprimez-le quand vous aurrez besoin de ces lignes.
Attention : si la ligne invalidée est contient une guillemet (pour une
chaine), cela peut générer une erreur de syntaxe. Remplacez cette
guillement par un autre caractère et n'oubliez pas de la replacer quand
vous aurrez besoin de cette ligne.