Autorisation : Membre
Nb de messages : 57
Inscrit le : Jeu 08 Oct 2009, 20:56
Posté le : Jeu 20 Fév 2014, 0:18
Salut,
Je vous propose ce soir un jeu que j'ai codé il y a un moment déjà (donc si y'a de l'opti à faire, et oooh oui il y en aura, n'hésitez pas), une sorte de snake un peu modifié.
Vous êtes un personnage se déplaçant sur l'écran, qui ne grossit pas lorsqu'il chope des points.
Vous avez en fait 30 secondes (approximativement, dépend de la mémoire de la calto et sa pu-pu-pu-puissance) pour choper un max de points. Une autre sorte d'item ramassable, le "pi", vous fait regagner 2 secondes sur le timer quand vous le chopez.
Le but étant de tenir le plus longtemps. Je fais dans les 35-40 points et c'est pas mal
Le prog. fait 517 octets mais y'a bien sûr moyen de faire mieux. Je voulais notamment savoir si l'utilisation d'une liste diminuerait le temps d'accès à mes variables plutôt que d'utiliser les variables standard, mais je n'ai pas encore testé.
Le jeu est assez fluide pour être jouable mais tout juste.
J'ai voulu rajouter un item malus qui fait perdre du temps mais ça ramait trop !
Codé avec une 82 stats fr. Je commente avec //. J'indente pour la lisibilité du code.
Code
EffEcr
For(A,1,8
Output(A,1,"!"
Output(A,16,"!" // Affichage du field (les choses qui ne varient pas)
End
Output(1,2,"--SCORE :")
Output(1,14,"--")
Output(8,2,"-TEMPS : ")
2->A:2->B // Coordonnées d'effacement de trace du perso
0->S:0->K // S : Score, K : getKey
2->X:2->Y // Cordonnées du perso
30->E // Temps
entAléat(2,7->C
entAléat(2,15->D // Placement aléat. de l'item à point
entAléat(2,7->F // Placement aléat. de l'item à temps
entAléat(2,15->G
For(E,30,0,-0.2)
If K=45: Goto 0 // Bon là j'avais juste la flemme de faire autre chose... Ce n'est qu'un Goto de sortie du programme donc y'a pire. Annul pour quitter
Output(1,12,S
Output(8,11,E
If E>=10
Then
Output(8,15,"-"
Else
If E >=1
Then
Output(8,14,"--"
Else
Output(8,13,"---"
End
End
Output(C,D,"*"
Output(A,B," "
Output(Y,X,"[theta]") // Le symbole theta, on est d'accord
Output(F,G,"[pi]") // Idem
Y->A:X->B
codeTouche->K
X-(K=24)+(K=26)->X // Déplacement du perso
Y-(K=25)+(K=34)->Y
X+(X=1)-(X=16)->X // Collisions
Y+(Y=1)-(Y=8)->Y
If A=C et B=D // Si on a chopé l'item à point
Then
entAléat(2,7->C
entAléat(2,15->D
S+1->S
End
If A=F et B=G // Si on a chopé l'item à temps
Then
entAléat(2,7->F // On le re-génère
entAléat(2,15->G
E+2->E
End
End
EffEcr
Output(3,4,"GAME OVER")
Output(4,6,"SCORE :"
Output(5,8,S
Output(6,1," FAITES ENTREE "
Pause
Lbl 0
EffEcr
Output(1,1,"
J'ai déjà modifié quelques trucs par rapport à avant en écrivant ceci ça tourne plus vite.
Je ne suis notamment pas fier du bidouillage au milieu du programme pour afficher le temps joliment.
(Le If E >= 10 etc...) En plus ça reste moche sur la fin si on regarde bien le timer lorsqu'il passe en-dessous de 1. Je me croyais malin en mettant Output(8,11,partEnt(E)) mais ça faisait juste tout planter alors que je pensais vraiment qu'afficher la partie entière de E suffirait.
Finalement je pense que j'aurai beau faire toutes les optimisations du monde, la vitesse de déplacement du personnage dépend du temps, on ne peut pas faire plus d'un déplacement en 0.2 secondes, qui est le pas de la boucle principale du temps, puisque dans cette boucle il n'y a qu'un seul getKey...
Est-ce que j'en mets un 2e ? Ça me paraît à la fois foireux et à la fois je me dis que ça peut fonctionner.
Enfin bref, le commun des mortels appréciera tout de même ce petit jeu distrayant.
Autorisation : Membre
Nb de messages : 3738
Inscrit le : Lun 19 Oct 2009, 21:25
Posté le : Jeu 20 Fév 2014, 0:46
Ne mentionne pas le jeu snake dans un titre de sujet d'un jeu qui n'a rien à voir avec snake...
Concept de jeu intéressant.
Si tu t'obstines à utiliser uniquement des données numériques à déplacer sans hiérarchie variable, alors les variables numériquent demeurent certainement plus efficaces (tant par réputation que par logique même du système d'exploitation).
De toute façon ici tu n'as besoin que de variables numériques. (pas de queue de serpent par exemple)
Tandis que les listes permettent de hiérarchiser les données avec d'autres variables. Les listes permettent ainsi de ne pas déplacer de données mais plutôt de changer un index et c'est ça le plus important, car chaque déplacement monopolise beaucoup de ressources et la taille de la base de données a une forte influence sur le temps total de glissement des données. On peut même utiliser un bug du tri de liste pour ceux qui s'obstinent à travailler en déplacement de données.
(ce bug est de donner un index constant aux fonctions de tri croissant ou décroissant SortA,SortD,TriCroi,TriDécroi et de se retrouver quand même avec une permutation circulaire des données)
Je tolère les goto pour sortir d'un programme, et de toute façon chacun choisi sa voie. Mais ce n'est vraiment pas élégant.
Mettre plusieurs getKey me semble vraiment foireux. Et je ne vois pas ce que tu veux dire.
Si on pousse le concept plus loin de façon générale, tu voudrais certainement avoir un tampon des touches pressées. La TI a un tampon pour les deux premières touches pressées après avoir été disponible.
Mais cela ne résoudra pas les limites de la boucle.
((S'il n'y avait pas de pression systématique des touches, alors tu aurais pu éviter les calculs de déplacement avec des tests supplémentaires pour gagner en rapidité lorsqu'aucune touche n'est pressée.))
---------------------- ti82statfr: 2008, inscrit: 2009, ti84pocketfr: noël2011, ti30xbmultiview: iut 2012-2014
Perfectionniste, manque tact. Pas le temps de tout publier depuis 2011. Répond toujours aux questions. (rédigé juin 2014)
Autorisation : Membre
Nb de messages : 57
Inscrit le : Jeu 08 Oct 2009, 20:56
Posté le : Jeu 20 Fév 2014, 1:23
Ok donc je garde mes variables.
Ce que je veux dire par plusieurs getKey, c'est si j'en mets 2 dans ma boucle est-ce que ça voudrait dire qu'en un tour de boucle je peux avoir le temps de presser 2 touches ?
Mais bon c'est pas ce qui me chagrine le plus.
Je trouve dommage de ne pas pouvoir rajouter de contenu simplement parce que la calculatrice n'est pas assez puissante; n'y a-t-il vraiment pas moyen de faire plus rapide ?
Et à part ça, ce qui m'embête le plus c'est que j'aimerais afficher le temps en tant qu'entier.
Là, ça m'affiche le pas de 0.2 (30, 29.8, 29.6 etc) donc de une c'est pas beau et de deux ça me force à adapter le coin inférieur droit de l'écran en fonction de la valeur du temps pour que ça reste joli (comme je n'utilise pas EffEcr, si je n'ai pas tous les If E >= 10 etc, alors j'ai des valeurs qui se chevauchent au fur et à mesure que E diminue)
Y'a pas moyen de faire ça ?
Si je veux afficher Output(8,11,partEnt(E)) ça descend E de 1 à chaque pas, ça n'affiche pas le perso ni les items, seulement à la fin, lorsque E tombe à 0 et alors ça crashe...
Autorisation : Membre
Nb de messages : 3738
Inscrit le : Lun 19 Oct 2009, 21:25
Posté le : Jeu 20 Fév 2014, 1:44
Ce n'est pas avoir deux getKey qui permettra d'effectuer deux calculs de déplacement. Et puis la TI garde toujours en mémoire une touche supplémentaire même quand la précédente n'a pas encore été captée par un getKey. Tu n'auras toujours que de l'avance dans la saisie, pas un gain de rapidité.
Tu peux éviter toute action innutile y compris un calcul qui ne change pas une valeur.
Un simple test de valeur de touche peut être plus efficace que d'effectuer systématiquement un calcul, parfois même sans effet.
Donc l'optimisation de code booléenne n'est pas forcément satisfaisante en rendement.
Par exemple tu fais ceci ou tu reviens à la forme classique en plusieurs tests.
Code
If max(K={24,26
X-(K=24)+(K=26)->X
If max(K={25,34
Y-(K=25)+(K=34)->Y
Tu peux placer judicieusement les calculs, la saisie, les affichages, et les effacement pour ne pas stocker les anciennes coordonnées.
A moins que tu rejètes des clignotements, tu peux afficher un effacement du nombre entier plutôt que d'effacer uniquement les poids faibles.
Tu peux enlever la partie décimale au moment de l'affichage : iPart(T), int(T), mode Fix0 précédemment.
Tu peux calculer la taille du nombre avec le log(X) (X non nul!) à l'intérieur d'un unique Output plutôt que d'utiliser deux alternatives.
Et pour supporter zéro en booléen, log(X+not(X))
---------------------- ti82statfr: 2008, inscrit: 2009, ti84pocketfr: noël2011, ti30xbmultiview: iut 2012-2014
Perfectionniste, manque tact. Pas le temps de tout publier depuis 2011. Répond toujours aux questions. (rédigé juin 2014)
Autorisation : Membre
Nb de messages : 57
Inscrit le : Jeu 08 Oct 2009, 20:56
Posté le : Jeu 20 Fév 2014, 2:39
Ok merci pour tes astuces.
Puissant le coup du max ! Je savais pas qu'on pouvait faire ça.
Du coup, le nouveau code :
Code
EffEcr
For(A,1,8
Output(A,1,"!"
Output(A,16,"!" // Affichage du field (les choses qui ne varient pas)
End
Output(1,2,"--SCORE :")
Output(1,14,"--")
Output(8,2,"-TEMPS : ")
Output(8,14,"--")
2->A:2->B // Coordonnées d'effacement de trace du perso
0->S:0->K // S : Score, K : getKey
2->X:2->Y // Cordonnées du perso
30->E // Temps
entAléat(2,7->C
entAléat(2,15->D // Placement aléat. de l'item à point
entAléat(2,7->F // Placement aléat. de l'item à temps
entAléat(2,15->G
For(E,30,0,-0.2)
If K=45: Goto 0 // Bon là j'avais juste la flemme de faire autre chose... Ce n'est qu'un Goto de sortie du programme donc y'a pire. Annul pour quitter
Output(1,12,S
Output(8,11,ent(E)
Output(C,D,"*"
Output(A,B," "
Output(Y,X,"[theta]") // Le symbole theta, on est d'accord
Output(F,G,"[pi]") // Idem
Y->A:X->B
codeTouche->K
If max(K={24,26
Then
X-(K=24)+(K=26)->X
X+(X=1)-(X=16)->X
End
If max(K={25,34
Then
Y-(K=25)+(K=34)->Y
Y+(Y=1)-(Y=8)->Y
End
If A=C et B=D // Si on a chopé l'item à point
Then
entAléat(2,7->C
entAléat(2,15->D
S+1->S
End
If A=F et B=G // Si on a chopé l'item à temps
Then
entAléat(2,7->F // On le re-génère
entAléat(2,15->G
E+2->E
End
End
EffEcr
Output(3,4,"GAME OVER")
Output(4,6,"SCORE :"
Output(5,8,S
Output(6,1," FAITES ENTREE "
Pause
Lbl 0
EffEcr
Output(1,1,"
Autorisation : Membre
Nb de messages : 3738
Inscrit le : Lun 19 Oct 2009, 21:25
Posté le : Jeu 20 Fév 2014, 13:12
Mon article des booléens explique beaucoup de choses dont l'utilsation de max() à la place de OU.
Cependant essaie avec l'écriture complète : If K=24 or K=26 , plutôt que max :
1-car l'optimisation de code avec max n'est forcément rapide, vérifie donc
2-car les conditions entre un nombre scalaire et des termes de liste n'existent qu'à partir de la ti82stats.
J'insiste encore sur l'ordre des actions, car stocker d'anciennes coordonnées est une perte de temps non-négligeable.
J'insiste sur l'activation du mode Fix0 (le zéro à droite de Float dans le menu mode) car il permet de ne pas utiliser iPart/ent. Cela économise forcément un peu de temps, même négligeable. Pourvu que tu remettes un mode plausible tel que Float à la fin du programme.
Tu n'as plus d'effacement des poids faibles du temps décroissant et la TI cadre à gauche avec Output. Donc le changement de décade abandonnera des zéros indésirables.
---------------------- ti82statfr: 2008, inscrit: 2009, ti84pocketfr: noël2011, ti30xbmultiview: iut 2012-2014
Perfectionniste, manque tact. Pas le temps de tout publier depuis 2011. Répond toujours aux questions. (rédigé juin 2014)