Sauvegarder des données, savoir si le programme a déjà été lancé, compresser des informations, tout est à votre portée!
Bonjour à tous !
Tout d'abord je sais que mon sujet n'est pas au bon endroit, mais en tant que simple membre je ne peux pas poster d'articles... Si un modo passe par là et qu'il le juge utile, se serait bien qu'il déplace le sujet vers la catégorie « Articles » si possible. Merci d'avance ! Problème réglé.
Vous voulez sauvegarder votre niveau dans un jeu ? Sauvegarder diverses données ? Ou encore réaliser une action seulement la première fois qu'on lance le programme ?
Alors vous êtes au bon endroit, car c'est ce que je vais essayer de vous apprendre !
Pour commencer, vous avez besoin de connaître les listes personnalisées, puisqu'on va devoir les utiliser . A cause de cela, malheureusement, il est impossible de le faire sur une Ti 82 (à moins d'utiliser une liste "basique" mais on est pas sur qu'un autre programme ne l'utilise pas du coup...)
Je tiens à préciser que certaines des astuces qui suivent m'ont été proposées par je ne me rappelle plus qui sur le forum de l'ancien tout 82. S'il y a déjà eut des articles à ce sujet, je ne les ai jamais lu...
1. Sauvegarder un meilleur score, ou une information qui doit être initialisée à 0
Pour mes explications, je vais prendre l'exemple d'un jeu de SNAKE.
On va considérer qu'on veut sauvegarder les 3 meilleurs scores.
Pour ce faire, nous allons stocker ces informations dans une liste personnalisée, LSNAKE par exemple. Les 3 meilleurs scores occuperont chacun un rang de la liste personnalisée.
Voilà maintenant vous savez comment sauvegarder vos meilleurs scores !
Tant que vous ne modifiez/supprimez pas la liste personnalisée, vos informations sont en (relative) sécurité
2. Savoir si un programme a déjà été lancé, et ainsi sauvegarder un niveau, ou une information qui doit être initialisée à une valeur non nulle
Imaginons maintenant que nous voulons sauvegarder le niveau le plus élevé qu'on a débloqué sur notre SNAKE.
Il suffit de faire comme pour les scores, me diriez vous : utiliser un terme de la liste LSNAKE pour simplement stocker le niveau.
Certes, mais un problème se pose très vite : on commence au niveau 1, or lorsqu'on créé la liste, si elle n'existe pas, tous les termes sont mis à 0... On pourrait considérer qu'en mémoire le niveau 1 vaut 0, le 2 vaudrait alors 1 etc, mais dans ce cas je ne pourrais pas vous apprendre ce que j'ai l'intention de dire, donc ça ne servirait à rien
La solution alternative est de pouvoir tester si le programme a déjà été lancé, et le cas échéant, initialiser les données qui ont besoin (le niveau à 1 par ex).
Remarque: Comme le signale Linka plus bas, on voit souvent des programmes nécessitant, pour être lancé la première fois, de lancer un autre programme qui va créer une liste personnalisée avec les valeurs initiales. Ceci est à éviter! En effet, il est vraiment peu pratique pour l'utilisateur de devoir lancer un autre programme la première fois qu'il veut l'utiliser! Utilisez plutôt ce que nous allons maintenant voir .
Réfléchissons un peu : il y a 2 choix possibles : soit le programme a été lancé, soit il ne l'a pas été.
Ce qu'il nous faudrait donc, c'est stocker une information qui contiendrait 1 (vrai) si le programme a déjà été lancé, et 0 sinon (puisque la liste sera initialisé avec des valeurs nulles si elle n'existait pas, ce qui nous convient parfaitement ! ).
On va alors fixer :
Codons sans plus tarder :
Petite remarque que fait Linka plus bas concernant les 83+:
3. Quelques remarques et optimisations par rapport aux codes précédents
A. Savoir si le programme a déjà été lancé à partir d'informations non nulles
A ce stade, on peut remarquer qu'en fait, le niveau ne vaudra jamais 0 (comme les meilleurs scores qui sont initialisés dans le code précèdent).
On peut donc s'en servir pour savoir si le jeu a déjà été lancé !
En effet, si le niveau vaut 0, c'est que la liste vient d'être initialisée, et sinon, que tout est ok, le jeu a déjà été lancé.
On peut donc faire :
B. Initialiser toutes les valeurs en une seule commande
Si vous avez plusieurs valeurs à initialiser, plutôt que de faire:
On peut remarquer que dans ce cas précis, où on stocke une liste dans une liste personnalisée, le nom de la liste suffit, ainsi, plutôt que de mettre LSNAKE on peut directement mettre SNAKE, la calto comprend qu'il s'agit d'une liste personnalisée nommée LSNAKE.
Par contre vous ne pouvez pas faire:
C. Compresser les données : Stocker plusieurs valeurs dans un seul terme de la liste
Dans un snake, on peut remarquer que notre score a un maximum qu'il ne peut pas dépasser.
En effet, l'écran fait 63*95=5985 pixels. Si on dessine un serpent avec des carrés de 3*3, avec un pixel entre chaque segment du serpent, on obtient un maximum de 5985/4/4=384 segments.
Ainsi, puisqu'on veut stocker 3 meilleurs scores, ça donne environ 400^3=64 000 000 possibilités maximum (on arrondi c'est pas important). On se rend donc compte qu'on peut stocker les 3 meilleurs scores, puisqu'il y a moins de 13 chiffres.
Donc, en s'y prenant bien, il est possible de stocker plusieurs informations dans le même terme de la liste.
Ici ce n'est certes pas très pratique (à cause des risques d'arrondis notamment comme le signale Linka plus bas), mais on peut faire mieux en fonction des informations à stocker.
Note: attention, si vous avez des nombres pouvant aller jusqu'à X, le facteur devra être de X+1.
Ex: Si vous voulez stocker plusieurs nombres compris entre 0 et 1, il faudra non pas multiplier par 1^N mais par 2^N:
Remarque: vous pouvez aussi stocker seulement des nombres négatifs en utilisant la méthode vue plus haut pour les nombres positifs (donc le terme de la liste utilisé sera négatif), mais attention à ne pas utiliser PartEnt (int en anglais), mais ent (iPart en français), sinon vous risquez d'être surpris par le résultat! Plus d'informations ici.
Autre remarque: stockez des nombres entiers avec ce système, et non des nombres décimaux (ou sinon faites attention à ne pas mélanger 2 données différentes, en fixant un maximum de chiffres).
Voici un exemple plus intéressant pour utiliser cette technique : vous avez un rpg et vous voulez sauvegarder si votre perso peut ou non utiliser le sort « feu » et le sort « glace ».
Et les nombres de signes opposés?
Il demeure un petit problème: comment faire pour stocker, dans un même terme de liste, des nombres de signes opposés?
Considérons que les nombres A et B à stocker dans C sont compris entre [ -9 ; 9].
Si on y réfléchi, il suffit d'ajouter 9 à cet intervalle pour que tous les nombres soient compris entre [ 0 ; 18], et soient ainsi tous positifs!
Il faut donc faire:
Et si l'intervalle ne commence pas à 0 on fait quoi?
Une dernière chose: Si vous avez des nombres compris entre 10 et 19 à compresser, faites comme pour les nombres dont le signe est inconnu:
Et si on a un intervalle du type [ -X ; -Y ] U [ Y ; X ] avec X>Y>0 ?
Il suffit de se se ramener à un intervalle [ -X + Y -1; X - Y + 1 ], et le tour est joué!
Ex: Soit A et B, compris dans l'intervalle [ -19 ; -10 ] U [ 10 ; 19 ] (je ne sais pas trop dans quel cas de figure vous pouvez avoir ça, mais on ne sait jamais )
Et pour un intervalle [ - V ; -W ] U [ X ; Y ] où X, Y, V et W >= 0 ?
Eh bien c'est la même chose en fait .
On se ramène à l'intervalle [ -V + W ; Y - X + 1 ]
Ex: Soit A et B compris entre [ -19 ; -10 ] U [ 20 ; 29 ] (notez que je ne sais toujours pas comment vous pouvez vous retrouver dans un cas pareil, mais je donne l'astuce à titre indicatif)
Dernière remarque: avec cette technique, on peut même compresser au maximum des nombres compris dans des réunions de 3, 4 ou 5 intervalles ! (voire même plus, mais là je crois que vous ne vous retrouverez définitivement jamais dans un cas pareil ): Il suffit de réduire progressivement le nombres d'intervalles dans la réunion considérée, comme on l'a fait plus haut pour passer de 2 à 1 intervalle.
Voilà vous savez maintenant comment utiliser les listes personnalisées pour sauvegarder tous types de données (en y réfléchissant un peu vous pouvez très bien stocker le nom du joueur, le mana, la vie, le niveau, des nombres négatifs, positifs, faire des intros si on y joue pour la première fois...).
La seule limite sera votre imagination !
Si vous avez des questions, suggestions, conseils, n'hésitez pas
PS:Merci à Linka pour son aide !
Je n'ai pas testé tous mes codes, si vous voyez une erreur, signalez là.
Bonjour à tous !
Vous voulez sauvegarder votre niveau dans un jeu ? Sauvegarder diverses données ? Ou encore réaliser une action seulement la première fois qu'on lance le programme ?
Alors vous êtes au bon endroit, car c'est ce que je vais essayer de vous apprendre !
Pour commencer, vous avez besoin de connaître les listes personnalisées, puisqu'on va devoir les utiliser . A cause de cela, malheureusement, il est impossible de le faire sur une Ti 82 (à moins d'utiliser une liste "basique" mais on est pas sur qu'un autre programme ne l'utilise pas du coup...)
Je tiens à préciser que certaines des astuces qui suivent m'ont été proposées par je ne me rappelle plus qui sur le forum de l'ancien tout 82. S'il y a déjà eut des articles à ce sujet, je ne les ai jamais lu...
1. Sauvegarder un meilleur score, ou une information qui doit être initialisée à 0
Pour mes explications, je vais prendre l'exemple d'un jeu de SNAKE.
On va considérer qu'on veut sauvegarder les 3 meilleurs scores.
Pour ce faire, nous allons stocker ces informations dans une liste personnalisée, LSNAKE par exemple. Les 3 meilleurs scores occuperont chacun un rang de la liste personnalisée.
- Code:
3->dim(LSNAKE //Grâce à cette instruction, si la liste n'existait pas, elle est créée, et remplie de 0, sinon elle est juste redimensionnée si besoin est (les cases manquantes étant remplies de 0)
//Le code de notre jeu
//Ici on considère que notre score est stocké dans S
For(A,1,3 //3 meilleurs scores
If S>LSNAKE(A //Nouveau meilleur Aème score
Then
LSNAKE(A->B //On récupère l'ancien Aème score
S->LSNAKE(A //On sauvegarde le nouveau Aème meilleur score
B->S //On charge le score déclassé, pour permettre un « décalage » des scores
End
End
Voilà maintenant vous savez comment sauvegarder vos meilleurs scores !
Tant que vous ne modifiez/supprimez pas la liste personnalisée, vos informations sont en (relative) sécurité
2. Savoir si un programme a déjà été lancé, et ainsi sauvegarder un niveau, ou une information qui doit être initialisée à une valeur non nulle
Imaginons maintenant que nous voulons sauvegarder le niveau le plus élevé qu'on a débloqué sur notre SNAKE.
Il suffit de faire comme pour les scores, me diriez vous : utiliser un terme de la liste LSNAKE pour simplement stocker le niveau.
Certes, mais un problème se pose très vite : on commence au niveau 1, or lorsqu'on créé la liste, si elle n'existe pas, tous les termes sont mis à 0... On pourrait considérer qu'en mémoire le niveau 1 vaut 0, le 2 vaudrait alors 1 etc, mais dans ce cas je ne pourrais pas vous apprendre ce que j'ai l'intention de dire, donc ça ne servirait à rien
La solution alternative est de pouvoir tester si le programme a déjà été lancé, et le cas échéant, initialiser les données qui ont besoin (le niveau à 1 par ex).
Remarque: Comme le signale Linka plus bas, on voit souvent des programmes nécessitant, pour être lancé la première fois, de lancer un autre programme qui va créer une liste personnalisée avec les valeurs initiales. Ceci est à éviter! En effet, il est vraiment peu pratique pour l'utilisateur de devoir lancer un autre programme la première fois qu'il veut l'utiliser! Utilisez plutôt ce que nous allons maintenant voir .
Réfléchissons un peu : il y a 2 choix possibles : soit le programme a été lancé, soit il ne l'a pas été.
Ce qu'il nous faudrait donc, c'est stocker une information qui contiendrait 1 (vrai) si le programme a déjà été lancé, et 0 sinon (puisque la liste sera initialisé avec des valeurs nulles si elle n'existait pas, ce qui nous convient parfaitement ! ).
On va alors fixer :
- Code:
LSNAKE(1) = 1 si prgm déjà lancé, 0 sinon
LSNAKE(2) = niveau
LSNAKE(3) = Meilleur score 1
LSNAKE(4) = Meilleur score 2
LSNAKE(5) = Meilleur score 3
Codons sans plus tarder :
- Code:
5->dim(LSNAKE //Grâce à cette instruction, si la liste n'existait pas, elle est créée, et remplie de 0
If non(LSNAKE(1 //Le premier terme contient 0 si le programme n'a jamais été lancé, et 1 sinon
Then
1->LSNAKE(1 //On sauvegarde le fait qu'on a déjà lancé le prgm
1->LSNAKE(2 //Niveau 1
10->LSNAKE(3 //Meilleur score 1 vaut 10 dès le début
7->LSNAKE(4 //Meilleur score 2 vaut 7 dès le début
5->LSNAKE(5 //Meilleur score 3 vaut 5 dès le début
//On peut aussi faire d'autres actions (une petite intro au jeu, afficher les règles, etc)
End
//Le code de notre jeu
//Gestion des meilleurs scores
For(A,3,5 //Ne pas oublier de modifier le numéro des termes des meilleurs scores
If S>LSNAKE(A
Then
LSNAKE(A->B
S->LSNAKE(A
B->S
End
End
Petite remarque que fait Linka plus bas concernant les 83+:
Linkakro a écrit:Sâchez que la ti83plus et ses successeurs supportent la dimension nulle des listes. Ainsi il suffit que la liste soit définie, même si elle est vide, pour savoir s'il faut initialiser.
Toutefois l'économie de mémoire et de méthode n'est pas particulièrement intéressante. Elle permet juste de se passer dans tous les cas du terme de contrôle de l'initialisation (le premier terme dans les exemples partie 2 et 3)
- Code:
// initial
If non(dim(lSNAKE
Then
// création
End
////////
//nettoyage
EffListe lSNAKE
Les bribes de code ci-dessus dans une ti83plus pourront remplacer la méthode présentée précédemment avec le premier terme même si on traite des données qui peuvent être nulles. Sur un modèle tel que 82stat, il faudra utiliser une des méthodes du tutoriel.
3. Quelques remarques et optimisations par rapport aux codes précédents
A. Savoir si le programme a déjà été lancé à partir d'informations non nulles
A ce stade, on peut remarquer qu'en fait, le niveau ne vaudra jamais 0 (comme les meilleurs scores qui sont initialisés dans le code précèdent).
On peut donc s'en servir pour savoir si le jeu a déjà été lancé !
En effet, si le niveau vaut 0, c'est que la liste vient d'être initialisée, et sinon, que tout est ok, le jeu a déjà été lancé.
On peut donc faire :
- Code:
4->dim(LSNAKE
If non(LSNAKE(1 //Le premier terme contient 0 si le programme n'a jamais été lancé, et le niveau sinon
Then
1->LSNAKE(1 //Niveau 1, on a lancé le prgm
End
//Le code de notre jeu
//Gestion des meilleurs scores
For(A,2,4 //Ne pas oublier de modifier le numéro des termes des meilleurs scores
If S>LSNAKE(A
Then
LSNAKE(A->B
S->LSNAKE(A
B->S
End
End
B. Initialiser toutes les valeurs en une seule commande
Si vous avez plusieurs valeurs à initialiser, plutôt que de faire:
- Code:
1->LSNAKE(1 //On sauvegarde le fait qu'on a déjà lancé le prgm
1->LSNAKE(2 //Niveau 1
10->LSNAKE(3 //Meilleur score 1 vaut 10 dès le début
7->LSNAKE(4 //Meilleur score 2 vaut 7 dès le début
5->LSNAKE(5 //Meilleur score 3 vaut 5 dès le début
- Code:
{1,1,10,7,5->SNAKE
On peut remarquer que dans ce cas précis, où on stocke une liste dans une liste personnalisée, le nom de la liste suffit, ainsi, plutôt que de mettre LSNAKE on peut directement mettre SNAKE, la calto comprend qu'il s'agit d'une liste personnalisée nommée LSNAKE.
Par contre vous ne pouvez pas faire:
- Code:
1->SNAKE(1 //Ne fonctionne pas!
//Alors que
L1->SNAKE //Fonctionne!
C. Compresser les données : Stocker plusieurs valeurs dans un seul terme de la liste
Dans un snake, on peut remarquer que notre score a un maximum qu'il ne peut pas dépasser.
En effet, l'écran fait 63*95=5985 pixels. Si on dessine un serpent avec des carrés de 3*3, avec un pixel entre chaque segment du serpent, on obtient un maximum de 5985/4/4=384 segments.
Ainsi, puisqu'on veut stocker 3 meilleurs scores, ça donne environ 400^3=64 000 000 possibilités maximum (on arrondi c'est pas important). On se rend donc compte qu'on peut stocker les 3 meilleurs scores, puisqu'il y a moins de 13 chiffres.
Donc, en s'y prenant bien, il est possible de stocker plusieurs informations dans le même terme de la liste.
- Code:
//Soit A, B, C et D les 4 meilleurs scores à sauvegarder
A400^2+B400+C+D/400->LSNAKE(3
//Maintenant on peut restaurer comme suit: (code donné par Linka plus bas)
LSNAKE(3->X //Pour gagner un peu de place
partEnt(Rép/400^2->A
partEnt((X-400A)/400->B
partEnt(X-B400-A400^2->C
partEnt((X-C-B400-A400^2)*400->D
{A,B,C,D
Ici ce n'est certes pas très pratique (à cause des risques d'arrondis notamment comme le signale Linka plus bas), mais on peut faire mieux en fonction des informations à stocker.
Note: attention, si vous avez des nombres pouvant aller jusqu'à X, le facteur devra être de X+1.
Ex: Si vous voulez stocker plusieurs nombres compris entre 0 et 1, il faudra non pas multiplier par 1^N mais par 2^N:
- Code:
A*2^3+B*2²+C*2+D
Remarque: vous pouvez aussi stocker seulement des nombres négatifs en utilisant la méthode vue plus haut pour les nombres positifs (donc le terme de la liste utilisé sera négatif), mais attention à ne pas utiliser PartEnt (int en anglais), mais ent (iPart en français), sinon vous risquez d'être surpris par le résultat! Plus d'informations ici.
Autre remarque: stockez des nombres entiers avec ce système, et non des nombres décimaux (ou sinon faites attention à ne pas mélanger 2 données différentes, en fixant un maximum de chiffres).
Voici un exemple plus intéressant pour utiliser cette technique : vous avez un rpg et vous voulez sauvegarder si votre perso peut ou non utiliser le sort « feu » et le sort « glace ».
- Code:
1->dim(LPOUV
//On restaure les pouvoirs
partEnt(LPOUV(1->A
2partDéc(LPOUV(1->B
//Code du jeu
//Sauvegarde des sorts (on considère que si A=1 alors on peut utiliser « feu», et que si B=1 on peut utiliser « glace», avec sinon respectivement A=0 et B=0)
A+B/2->LPOUV(1
- Code:
LPOUV(1)=0.0 « feu » désactivé ; « glace » désactivé ;
LPOUV(1)=1.0 « feu » activé ; « glace » désactivé ;
LPOUV(1)=0.5 « feu » désactivé ; « glace » activé ;
LPOUV(1)=1.5 « feu » activé ; « glace » activé ;
Et les nombres de signes opposés?
Il demeure un petit problème: comment faire pour stocker, dans un même terme de liste, des nombres de signes opposés?
Considérons que les nombres A et B à stocker dans C sont compris entre [ -9 ; 9].
Si on y réfléchi, il suffit d'ajouter 9 à cet intervalle pour que tous les nombres soient compris entre [ 0 ; 18], et soient ainsi tous positifs!
Il faut donc faire:
- Code:
//On stocke:
19(A+9)+B+9->C
//On récupère:
-9+PartEnt(C/19->A
C-19(A+9->B
Et si l'intervalle ne commence pas à 0 on fait quoi?
Une dernière chose: Si vous avez des nombres compris entre 10 et 19 à compresser, faites comme pour les nombres dont le signe est inconnu:
- Code:
//Plutôt que de faire:
A*20+B->C
ParEnt(C/20->A
C-20A->B
//Faites plutôt:
(A-10)*20+B-10->C
10+ParEnt(C/20->A
C-20(A-10)+10->B
Et si on a un intervalle du type [ -X ; -Y ] U [ Y ; X ] avec X>Y>0 ?
Il suffit de se se ramener à un intervalle [ -X + Y -1; X - Y + 1 ], et le tour est joué!
Ex: Soit A et B, compris dans l'intervalle [ -19 ; -10 ] U [ 10 ; 19 ] (je ne sais pas trop dans quel cas de figure vous pouvez avoir ça, mais on ne sait jamais )
- Code:
//Pour stocker:
//Je détaille un peu plus pour que vous puissiez me suivre:
A+9((A<0)-(A>0->A //Maintenant A est compris entre [ -10 ; -1 ] U [ 1 ; 10 ], soit [ -10 ; 10 ], ce qu'on sait traiter
B+9((B<0)-(B>0->B
21(A+10)+B+10->C
//Pour restaurer:
-10+PartEnt(C/21->A
C-21(A+10->B //A et B sont entre [ -10 ; 10 ]
A-9((A<0)-(A>0->A
B-9((B<0)-(B>0->B
Et pour un intervalle [ - V ; -W ] U [ X ; Y ] où X, Y, V et W >= 0 ?
Eh bien c'est la même chose en fait .
On se ramène à l'intervalle [ -V + W ; Y - X + 1 ]
Ex: Soit A et B compris entre [ -19 ; -10 ] U [ 20 ; 29 ] (notez que je ne sais toujours pas comment vous pouvez vous retrouver dans un cas pareil, mais je donne l'astuce à titre indicatif)
- Code:
//On stocke:
A+10(A<0)-19(A>0->B //On a a compris entre [ -9 ; 10 ]
B+10(B<0)-19(B>0->B
20(A+9)+B+9->C
//Pour restaurer:
-9+PartEnt(C/20->A
C-20(A+9->B //A et B sont entre [ -9 ; 10 ]
A-10(A<=0)+19(A>0->B
B-10(B<=0)+19(B>0->B
Dernière remarque: avec cette technique, on peut même compresser au maximum des nombres compris dans des réunions de 3, 4 ou 5 intervalles ! (voire même plus, mais là je crois que vous ne vous retrouverez définitivement jamais dans un cas pareil ): Il suffit de réduire progressivement le nombres d'intervalles dans la réunion considérée, comme on l'a fait plus haut pour passer de 2 à 1 intervalle.
Voilà vous savez maintenant comment utiliser les listes personnalisées pour sauvegarder tous types de données (en y réfléchissant un peu vous pouvez très bien stocker le nom du joueur, le mana, la vie, le niveau, des nombres négatifs, positifs, faire des intros si on y joue pour la première fois...).
La seule limite sera votre imagination !
Si vous avez des questions, suggestions, conseils, n'hésitez pas
PS:Merci à Linka pour son aide !
Je n'ai pas testé tous mes codes, si vous voyez une erreur, signalez là.
Dernière édition par m@thieu41 le Jeu 8 Aoû 2013 - 12:44, édité 11 fois