|
Posté le 01-06-2021 à 11:00 | #
|
Super ! Il y a justement le week-end de test cette semaine, ce sera une bonne occasion pour moi de retester et pour d'autres de découvrir avec les bugs corrigés. |
|
|
Posté le 02-06-2021 à 16:26 | #
|
For 1 -> E To O
For 1 -> F To M
If Mat A[E, F] = 0 :Then
1 -> D
E -> X
F -> Y
{X} -> List 1
{Y} -> List 2
Do
X -> List 1[Dim List 1 + 1]
Y -> List 2[Dim List 2 + 1]
X + (D = 1) - (D = 3) -> S
Y - (D = 2) + (D = 4) -> T
(S > 0) * (S < N) * (T > 0) * (T < M) => Mat A[S, T] = 0 => Isz D
X + (D = 2) - (D = 4) -> S
Y - (D = 3) + (D = 1) -> T
If (S > 0) * (S < N) * (T > 0) * (T < M) :Then
Mat A[S, T] = 1 => D - 1 -> D
Else
D - 1 -> D
IfEnd
D = 5 => 1 -> D
D = 0 => 4 -> D
X + (D = 2) - (D = 4) -> X
Y - (D = 3) + (D = 1) -> Y
LpWhile (X = E) * (Y = F) + (X < O)
If X < O :Then
For Min(List 1) -> E To Max(List 1)
ClrList 3
0 -> D
For 1 -> X To Dim List 1
If D = 0 :Then
If List 1[X] = E :Then
1 -> D
List 2[X] -> List 3[1]
IfEnd
Else
List 1[X] = E => List 2[X] -> List 3[1 + Dim List 3]
IfEnd
Next
For Min(List 3) -> F To Max(List 3)
Mat A[E, F] = 1 => 2 -> Mat A[E, F]
Next
Next
IfEnd
IfEnd
Next
Next
J'ai un problème avec ce bout de code.
Il est sensé détecter les "bulles" vides dans la grille du tetris.
Il fonctionne ainsi :
Dès qu'un espace vide est détecté (0 dans la matrice) le programme "longe le mur" qui borde l'espace vide avec un système de direction (variable D) et de test par rapport a la direction(si vide a gauche tourne a gauche et avance, si bloc devant tourne a droite sinon tout droit). Si le système revient sur la cellule de départ sans monter au dessus de la hauteur maximale des blocs (variable O) alors les lignes "dans" le "périmètre" du vide son comblé avec le nombre 2 : le jeu de la vie.
Le code ne fonctionne pas et il boucle parfois infiniment.
Si qqn a une idée ou a déjà fait ce genre de chose je suis preneur. |
|
|
Posté le 02-06-2021 à 16:50 | #
|
Est-ce que ton but c'est "simplement" de trouver toute la zone vide et de vérifier qu'elle ne dépasse pas la hauteur maximale des blocs ? Si c'est bien ça, je pense qu'il y a plus simple (un flood fill !). J'ai tenté de lire ton code mais sans trop d'explications sur les variables c'est difficile.
Un bug potentiel c'est si par exemple tu vas vers le haut et que tu arrives dans une impasse. Tu vas tenter de tourner à droite mais à droite c'est aussi un bloc plein et donc tu rentres dans les blocs pleins ; à partir de là, tout est possible. Je ne sais pas si ça se produit dans ton code mais tu t'en rendras sans doute compte rapidement. |
|
|
Posté le 02-06-2021 à 18:56 | #
|
Effectivement j'ai ce type de bug, quand j'ai une ligne de 2 blocs de longs, le programme tourne en rond sur 4 cases.
Je me suis renseigné sur la méthode que tu me conseille et effectivement je vais faire ça, j'y avait pensé au début mais je me suis dit qu'il était possible de faire plus rapide.
Merci pour ton aide, j'espère ne pas avoir trop de bugs avec cette méthode. |
|
|
Posté le 02-06-2021 à 20:52 | #
|
Si ça peut t'aider, voici un guide. Le flood fill c'est un parcours de graphe, si tu connais. Tu peux le faire en récursif mais la récursivité ça marche pas trop en Basic, donc le plus simple c'est de le faire en itératif.
En partant de ton point de départ, tu stockes une liste de cases vides à traiter. À chaque étape tu prends une case dans la liste : si elle atteint le sommet du jeu alors tu arrêtes parce que tu as déterminé que les règles du jeu de la vie ne s'appliquent pas, et sinon tu ajoute à la liste des cases à traiter tous les voisins vides que tu n'as pas encore vus.
Il faut donc une liste (disons de nombres complexes) pour stocker les numéros des cases à traiter, et une liste ou matrice pour noter quelles case tu as déjà vues. Pour faire simple je prends une matrice B dans cet exemple, mais tu peux aussi ajouter 1000 aux éléments de la matrice A quand tu les vois par exemple (et à la fin tout passer modulo 1000 pour effacer les traces).
Essentiellement, ça donne ça (non testé) :
// Liste de cases à traiter, à commencer par (A,B)
{A+iB}→List 1
// Matrices des cases vues
Dim Mat A→Dim Mat B
// Tant que la liste est non-vide, tu prends un élément
While Dim List 1
List 1[1]→A
ImP A→B
ReP A→A
// Retirer l'élément de la liste (on peut faire plus élégant)
Seq(List 1[I],I,2,Dim List 1)→List 1
// Noter qu'on l'a vu
1→Mat B[A,B]
// Si l'élément est hors grille, on arrête
A≥7⇒Goto F
// Ajouter les voisins vides non vus
A>0 And Mat A[A-1,B]=0 And Mat B[A-1,B]=0⇒List 1+{A-1+iB}→List 1
// etc x4
WhileEnd
// On n'a pas atteint le sommet → jeu de la vie
Lbl F
// On a atteint le sommet → rien |
|
|
Posté le 02-06-2021 à 21:00 | #
|
Désolé mais j'ai codé avant de voir ton message.
En fait j'ai pris le problème à l'envers : je met tout les blocs du "haut" a 0.5 ensuite je convertis tout les "0" en "2" (jeu de la vie).
Et pour finir Int(Mat A)->Mat A remet tout en ordre.
Ta méthode serait probablement plus rapide et plus propre mais au moins ça marche.
|
|
|
Posté le 02-06-2021 à 21:03 | #
|
Tout va bien du coup ! Si ça marche, il n'y a plus rien à ajouter. N'oublie pas quelques images pour clarifier les règles ! |
|
|
Posté le 03-06-2021 à 20:12 | #
|
Et voila enfin la version fonctionnel (elle n'est pas encore parfaite) du programme.
Les graphismes on été modifiés, j'ai rajouté un menu des options, un compteur de score, une vitesse qui augmente avec le temps.
Cependant, entre deux tours le temps de chargement est très très très long.
Une sorte de barre de chargement vous aidera à aller chercher un café attendre.
Amusez-vous. |
|
|
Posté le 06-06-2021 à 09:56 | #
|
Hey, je suis en train de tester le jeu, par contre il y a un comportement que je ne comprends pas trop :
Quand un objet descendant s'arrête sur un objet déjà en place, la ligne inférieure du premier fusionne avec la ligne supérieure du second. Je ne sais pas si je suis très clair x)
C'est prévu dans le code ou c'est un bug ? |
|
|
Posté le 06-06-2021 à 10:08 | #
|
Tu veut dire que graphiquement les blocs se "collent" ou deux lignes deviennent une seul ? |
|