Tetris comme imprimeur


En tournant, en réorganisant et en abaissant une séquence de formes prédéterminée, Tetris Printer Algorithm utilise la mécanique de Tetris pour générer des bitmaps arbitraires.

Description de l'algorithme


L'algorithme convertit les pixels de l'image source en carrés du champ Tetris ligne par ligne, se déplaçant de bas en haut. Pour générer un seul carré, l'algorithme assemble une structure composée d'une zone rectangulaire qui est complÚtement supportée par un carré en dessous. Une fois l'assemblage de la région rectangulaire terminé, ses lignes sont effacées, laissant un carré en dessous. Voici trois exemples de ce comportement.




Comme indiqué ci-dessous, l'algorithme peut également générer plusieurs carrés avec une seule structure.


Dans le processus de construction d'une ligne, tous les carrĂ©s ainsi crĂ©Ă©s doivent ĂȘtre basĂ©s sur quelque chose. Dans les images ci-dessus, les carrĂ©s gĂ©nĂ©rĂ©s sont sur le sol du terrain de jeu. Cependant, si une ligne arbitraire contient des trous, elle ne pourra pas fournir le support nĂ©cessaire pour construire une ligne au-dessus d'elle. L'algorithme rĂ©sout ce problĂšme en crĂ©ant une plate-forme plate au-dessus de la chaĂźne avec des trous. Dans l'animation ci-dessous, une plate-forme construite au sommet d'une ligne se compose d'un carrĂ© rouge. Une plate-forme est une structure temporaire et l'insertion de la derniĂšre forme la supprime.


La rangĂ©e de 5 carrĂ©s rouges illustrĂ©e ci-dessous est au-dessus de la rangĂ©e de 3 carrĂ©s rouges. Ceci est rĂ©alisĂ© en construisant une plate-forme plate en haut de la ligne du bas. La plateforme fournit le support nĂ©cessaire pour gĂ©nĂ©rer 5 carrĂ©s rouges. À la fin, la plate-forme est supprimĂ©e en insĂ©rant la derniĂšre forme et la nouvelle ligne se met en place. Notez que si l'algorithme doit gĂ©nĂ©rer des lignes dans l'ordre inverse (une ligne de 3 carrĂ©s rouges au-dessus d'une ligne de 5 carrĂ©s rouges), la plate-forme ne sera pas nĂ©cessaire.


Un motif carré


Pour référence, je donnerai les noms de 7 tetramino (piÚces de jeu).


La version de Tetris Printer Algorithm prĂ©sentĂ©e dans l'article est spĂ©cialement conçue pour le rendu des sprites d'anciens jeux vidĂ©o. Ces jeux contiennent des graphiques en 8 × 8 tuiles, et 2 octets ont Ă©tĂ© allouĂ©s pour chaque pixel. Par consĂ©quent, les sprites ne contenaient gĂ©nĂ©ralement que 3 couleurs plus des zones transparentes et avaient le plus souvent une taille de 16 × 16 ou 16 × 32 pixels.

L'animation ci-dessous montre tous les motifs utilisés pour créer des carrés individuels. Chaque motif utilise un tétramino interchangeable J, T et L, créant un seul carré en bas. L'algorithme attribue ce tétramino à l'une des 3 couleurs présentes dans le sprite. Le reste du tétramino se voit attribuer des couleurs arbitraires. Tout au long du gameplay, toutes les couleurs restent constantes.


En raison de la forme des trois tétraminos, il est impossible de créer un carré à partir des trois couleurs dans les deux premiÚres et les deux derniÚres colonnes. Par conséquent, la largeur minimale du terrain de jeu pour le rendu d'un sprite d'une largeur de 16 pixels est de 2 + 16 + 2 = 20 carrés. Cependant, il s'est avéré que 20 est trop peu.

Comme indiquĂ© ci-dessous, la zone au-dessus du carrĂ© infĂ©rieur unique ne peut pas ĂȘtre constituĂ©e d'une seule ligne, car les seules figures qui peuvent y entrer (tetramino I) n'ont aucun support.


Avec deux lignes, la seule façon d'étirer tout le terrain de jeu pour qu'il soit pris en charge est d'utiliser le tetramino S et Z. Mais dans ce cas, les trous resteront dans la ligne supérieure.


Le nombre minimum de lignes requises au-dessus du carrĂ© infĂ©rieur est de 3, et comme indiquĂ© plusieurs fois ci-dessus, de tels modĂšles existent. 20 carrĂ©s est la largeur minimale requise pour placer un sprite d'une largeur de 16 pixels. Mais 20 × 3 + 1 = 61, et ce nombre n'est pas divisible par 4, ce qui signifie qu'il ne peut pas ĂȘtre construit Ă  partir de tĂ©tramino. Cependant, une largeur de 21 nous donne 21 × 3 + 1 = 64, et il peut ĂȘtre construit Ă  partir de 16 tetramino. En fait, cette largeur permet Ă  l'algorithme de rendre les sprites jusqu'Ă  17 pixels de large.

Le terrain de jeu du Tetris original a une taille de 10 × 20 carrĂ©s (rapport 1: 2). Dans cette version de l'algorithme, ce rapport est prĂ©servĂ© - le terrain de jeu a une taille de 21 × 42 carrĂ©s.

Étant donnĂ© que le tĂ©tramino J, T et L sont interchangeables lors de la crĂ©ation d'un carrĂ©, et que 3 carrĂ©s de ces tĂ©tramino sont impliquĂ©s dans la crĂ©ation d'une ligne au-dessus, il existe 21 - 3 = 18 motifs pour crĂ©er un seul carrĂ©. Cependant, en raison de la symĂ©trie miroir, il n'y a en fait que 9. Il y a 3 lignes qui fonctionnent pour la plupart de ces 9. Cependant, une Ă©tude informatique approfondie a montrĂ© que les deux modĂšles avaient besoin de plus. La prochaine option possible est de 7 lignes, car 21 × 7 + 1 = 148, ce qui nĂ©cessite 37 tĂ©traminos. Comme le montrent les images ci-dessous, de tels modĂšles existent.



Motifs carrés multiples


Les motifs de crĂ©ation de plusieurs carrĂ©s sont limitĂ©s aux trois mĂȘmes couleurs crĂ©Ă©es par les motifs d'un seul carrĂ©. Les carrĂ©s rĂ©sultants sont crĂ©Ă©s Ă  partir de tetramino J, T et L, chacun occupant 3 carrĂ©s sur une ligne au-dessus de la ligne de crĂ©ation. Le nombre maximum de carrĂ©s pouvant potentiellement ĂȘtre crĂ©Ă©s avec un seul motif est 21/3 = 7. Cependant, pour les sprites d'une largeur de 16 pixels, le tĂ©tramino le plus Ă  droite ne peut pas crĂ©er un carrĂ©. MĂȘme dans le cas de sprites d'une largeur de 17 pixels, il peut crĂ©er un carrĂ© d'une seule couleur. Par consĂ©quent, le modĂšle de crĂ©ation Ă  partir de 7 carrĂ©s est rarement utilisĂ©.


Le nombre de modĂšles pour crĂ©er un nombre arbitraire de carrĂ©s peut ĂȘtre dĂ©terminĂ© en utilisant la combinatoire des Ă©numĂ©rations. ConsidĂ©rez le modĂšle ci-dessous, reprĂ©sentant une rangĂ©e au-dessus d'une rangĂ©e de trois carrĂ©s. Chaque bloc de trois carrĂ©s blancs adjacents dĂ©signe une partie de tetramino; les carrĂ©s crĂ©Ă©s ne sont pas affichĂ©s.


Trois tĂ©tramino crĂ©ent 4 vides. Il y a 21 - 3 × 3 = 12 carrĂ©s sombres qui peuvent ĂȘtre insĂ©rĂ©s arbitrairement dans ces vides pour former un motif spĂ©cifique. Le nombre de façons de distribuer ces carrĂ©s sombres peut ĂȘtre calculĂ© en les plaçant sur une ligne dans laquelle les carrĂ©s blancs simples sont traitĂ©s comme des sĂ©parateurs.


La tùche a donc été réduite au calcul de la valeur du coefficient du polynÎme. En regardant ces carrés blancs, vous pouvez comprendre qu'il s'agit du nombre de façons de choisir 3 sur 15. = 455.

Dans le cas général, pour n il est égal à . Mais en raison de la symétrie miroir, en fait, ils sont deux fois moins; si la quantité est impaire, puis en divisant par deux, nous arrondissons à l'entier le plus proche pour inclure le modÚle idéalement symétrique qui devrait exister dans cet ensemble, comme, par exemple, illustré ci-dessous pour le cas avec 455.


En appliquant cette formule à 7 tetramino, nous confirmons l'évidence: il n'y a qu'un seul motif pour créer 7 carrés.

Le modĂšle de crĂ©ation de 6 carrĂ©s peut ĂȘtre construit de deux maniĂšres: deux lignes pleines (2 × 21 + 6 = 48) et six lignes remplies (6 × 21 + 6 = 132), ce qui nĂ©cessite 12 et 33 tetramino. La formule ci-dessus montre qu'il existe 84 modĂšles pour crĂ©er 6 carrĂ©s, mais seulement 35 d'entre eux peuvent ĂȘtre construits Ă  partir de 2 lignes complĂštes. 49 modĂšles nĂ©cessitent 6 lignes. Les nombres sont impairs en raison des motifs symĂ©triques illustrĂ©s ci-dessous.



Il convient également de noter que 2 lignes sont possibles ici, car contrairement au modÚle de création d'un carré qui nécessitait le tétramino S et Z, 6 chiffres sont utilisés dans ces modÚles.

Le tableau ci-dessous indique le nombre de carrés créés par chaque type de motif, le nombre de lignes complÚtes, le nombre de tétramino utilisé et le nombre de motifs.

Carrés créésLignes complÚtesTetraminoPatterns
17 et 337 et 1619 (4 et 15)
2632136
3527455
4422715
5317462
62 et 612 et 3384 (35 et 49)
7171

Exemples de modĂšles.





Plateformes


Avant de construire une ligne, l'algorithme examine la ligne en dessous. Si la rangée du bas ne peut pas prendre en charge tous les carrés au-dessus, alors une plate-forme temporaire est nécessaire. Lorsque la plate-forme est supprimée, une nouvelle ligne descend, et en raison de la façon dont la gravité est implémentée dans le Tetris d'origine, certains carrés restent suspendus dans l'air.

L'illustration ci-dessous montre 10 modÚles de plate-forme. La construction de la plate-forme commence par abaisser le tétramino T au-dessus de l'un des carrés de la derniÚre ligne générée. Les tétraminos restants dépendent de ce premier T. Autrement dit, si la ligne générée précédente contient au moins 1 carré, comme le carré rouge dans l'image ci-dessous, nous pouvons créer une plate-forme plate au-dessus pour générer la ligne suivante.


Au milieu de la construction de la plate-forme, la ligne du bas est terminĂ©e et supprimĂ©e, laissant trois lignes au-dessus. Le dernier tĂ©tramino J ou L, qui supprimera ces lignes, n'est insĂ©rĂ© que lorsque les modĂšles de crĂ©ation gĂ©nĂšrent la ligne de sprite suivante au-dessus de la plate-forme. Cette derniĂšre figure empĂȘche la crĂ©ation de carrĂ©s dans les deux premiĂšres et derniĂšres lignes. Mais, comme mentionnĂ© ci-dessus, en raison de la gĂ©omĂ©trie du tĂ©tramino J, T et L utilisĂ© dans ce processus, les modĂšles de crĂ©ation de carrĂ©s sont limitĂ©s Ă  17 colonnes internes.

De plus, sur 19 façons possibles de construire des plates-formes au-dessus de Tetramino T, il n'y en a que 10 ci-dessus.

Matrices emballées


Comme indiqué ci-dessus, un sous-ensemble des 6 modÚles de création de carrés implique de ne supprimer que deux lignes. Tous les autres modÚles nécessitent 6 lignes. Pour comprendre pourquoi c'est le cas, considérez le modÚle ci-dessous.


Ces tetramino sont interchangeables avec tetramino J et L, et chacun d'eux ajoute 3 carrés adjacents à la rangée commune. Les lignes à compléter sont représentées par la matrice ci-dessous.


Maintenant, le tout consiste à emballer un espace vide avec du tetramino. En partant de la gauche, la seule option est d'utiliser la séquence tetramino I.


La seule façon de remplir l'espace restant est d'utiliser J et O ou I et L. Les deux options sont présentées ci-dessous.



Malheureusement, tetramino O et L ne sont pas pris en charge dans les matrices illustrées ci-dessus. Ce motif à 6 carrés nécessite une matrice plus grande.

Un problÚme similaire se pose dans deux modÚles de création d'un carré. Considérez la matrice ci-dessous:


La seule façon de remplir la ligne du bas à droite est d'enchaßner la séquence Z.


De mĂȘme, le seul moyen d'obtenir 3 cases vides en bas Ă  gauche est le tetramino S.

Dans la ligne médiane, il y a un carré vide entre S et Z et la seule façon de le remplir est d'utiliser le tétramino J, T ou L, comme indiqué dans les figures ci-dessous.



L'insertion de l'une de ces formes divise l'espace vide. La zone vide à gauche contient respectivement 5, 6 et 7 vides. Puisqu'aucune de ces valeurs n'est divisible par 4, il est impossible de continuer. Une matrice plus grande est requise pour ce motif carré unique.

Il en va de mĂȘme pour un autre motif de crĂ©ation d'un carrĂ©, illustrĂ© dans la matrice ci-dessous.


AprÚs avoir utilisé tetramino S et Z pour remplir la majeure partie de la ligne du bas, il y a un espace vide entre eux sur la ligne médiane.


Comme indiqué dans les images ci-dessous, l'insert de trou divise l'espace vide et la zone vide à gauche contient 9, 10 ou 11 carrés, respectivement; aucun des nombres n'est divisible par 4.



Mais l'emballage de matrices n'est pas le seul moyen de gĂ©nĂ©rer un motif de carrĂ©s. Par exemple, jetez un Ɠil au crĂ©ateur de 4 carrĂ©s ci-dessous.


Ce qui suit est une tentative de rendre le modÚle comme un ensemble de tétraminos emballés.


Le dernier L est ignoré, car un espace n'est formé qu'aprÚs l'achÚvement et la suppression de la troisiÚme ligne.

Mais aprÚs une recherche approfondie, il a été découvert que cette technique ne permet pas aux modÚles à un carré susmentionnés de fonctionner avec seulement 3 lignes. De plus, il ne lui permet pas d'implémenter de nouveaux motifs de 6 carrés sur deux lignes. Il n'est pas nécessaire de rechercher les motifs restants en dehors des matrices emballées, car ils utilisent déjà la plus petite quantité possible de tétramino. Et en nous limitant aux matrices emballées, nous trouverons tous les modÚles nécessaires beaucoup plus rapidement.

Recherche de motifs


Pour simplifier la sortie des donnĂ©es, l'algorithme d'imprimante Tetris se limite Ă  crĂ©er du tĂ©tramino au point central supĂ©rieur du terrain de jeu, Ă  le tourner, Ă  le dĂ©placer horizontalement et Ă  l'abaisser. Il n'a jamais Ă  dĂ©placer la figure horizontalement aprĂšs avoir passĂ© une certaine distance. Cette restriction rĂ©duit considĂ©rablement l'espace de recherche, car elle ne permet pas la formation de lacunes sous les chiffres ajoutĂ©s Ă  la matrice. À titre d'exemple, regardons la matrice des 3 carrĂ©s suivante.


Si nous jetons J au centre de la matrice, comme indiquĂ© ci-dessus, nous obtenons alors un espace de 2 carrĂ©s vides, qui ne peuvent pas ĂȘtre remplis avec les chiffres suivants. Par consĂ©quent, la recherche ne suivra pas ce chemin.


Étant donnĂ© que les espaces couverts ne sont pas autorisĂ©s, chaque colonne de la matrice peut ĂȘtre considĂ©rĂ©e comme une pile de carrĂ©s remplis et la hauteur de ces piles dĂ©crit pleinement le contenu de la matrice entiĂšre. Quel que soit le nombre de lignes, un tableau entier unidimensionnel Ă  21 Ă©lĂ©ments sera suffisant pour dĂ©crire une matrice bidimensionnelle.

Lorsqu'un chiffre tombe dans la matrice, les hauteurs des piles des colonnes correspondantes augmentent. Pour accélérer ce processus, toutes les tétramines sont analysées à l'avance. Il y a 19 tours tétramino, et la recherche considÚre chacun d'eux comme une figure unique.


Tetramino J dans le coin supĂ©rieur gauche de l'image occupe 3 colonnes. Lors de la descente sur la matrice, les hauteurs de 3 piles adjacentes augmentent respectivement de 1, 1 et 2 carrĂ©s. Mais avant que la figure puisse ĂȘtre abaissĂ©e, le profil infĂ©rieur de la figure doit correspondre au profil supĂ©rieur des piles respectives. Si ce J Ă©tait allongĂ© sur le sol du terrain de jeu, sous chacune de ces colonnes, il aurait dĂ» y avoir des espaces de 1, 1 et 0 cases vides. Étant donnĂ© que les dĂ©gagements sont interdits, les hauteurs relatives de 3 piles devront correspondre parfaitement au modĂšle.

Une autre conséquence de l'absence de lacunes est que lorsque les chiffres tombent dans la matrice, les rangées sont remplies de bas en haut. Il n'est pas possible de remplir une ligne au milieu d'une matrice avant ou sans compléter toutes les lignes en dessous. Dans le processus de remplissage de la matrice, sa limite inférieure remonte en fait. Par conséquent, une pile de colonnes de matrice peut fournir un support uniquement si sa hauteur moins le nombre de lignes terminées est supérieure à 0. Lorsqu'une forme est ajoutée à la matrice, au moins une des colonnes correspondantes doit fournir un support.

La recherche stocke un deuxiÚme tableau unidimensionnel contenant le nombre de carrés remplis dans chaque ligne. Le J ci-dessus contient dans les lignes correspondantes 3 et 1 un carré. Lorsque vous l'insérez dans la matrice, ces valeurs sont ajoutées aux éléments correspondants du tableau. Le nombre de lignes complétées est le nombre d'éléments avec une valeur de 21.

Comme indiquĂ© dans la section prĂ©cĂ©dente, si la figure ajoutĂ©e divise la matrice, les tailles des zones rĂ©sultantes doivent ĂȘtre divisĂ©es par 4. Par exemple, dans l'image ci-dessous, l'ajout de I crĂ©e 2 zones, chacune contenant 46 carrĂ©s vides. Puisque 46 n'est pas divisible par 4, il n'y a plus de moyen de remplir le reste de la matrice.


La sĂ©paration apparaĂźt lorsque la hauteur de la pile est Ă©gale Ă  la hauteur de la matrice. AprĂšs avoir insĂ©rĂ© la figure en incrĂ©mentant les hauteurs des piles respectives, les dimensions de toutes les zones divisĂ©es d'espace vide peuvent ĂȘtre dĂ©terminĂ©es en scannant le tableau de hauteurs et en ajoutant l'espace restant dans chaque pile. Ce nombre est vĂ©rifiĂ© et rĂ©initialisĂ© lorsqu'un fractionnement est dĂ©tectĂ©.

La recherche utilisée pour générer tous les modÚles utilise une construction incrémentale randomisée, un algorithme de retour en arriÚre qui vérifie systématiquement toutes les combinaisons dans un ordre aléatoire. La construction incrémentale d'une solution en insérant des formes au hasard la fait grandir comme un cristal. L'aléatoire fournit une irrégularité contenant des faces brisées qui servent de base aux formes ajoutées par la suite. La plupart de la matrice est emballée au hasard trÚs rapidement, et lorsque l'espace vide devient rare, le retour en arriÚre entre en jeu.

Avant d'effectuer la recherche, des permutations aléatoires de 371 façons d'ajouter un chiffre à la matrice sont effectuées. Le pseudo-code de la fonction de recherche est indiqué ci-dessous.

private Result search(Matrix matrix, int remaining) { if (remaining == 0) { return SOLUTION } attempts := attempts + 1 if (attempts >= MAX_ATTEMPTS) { return TIMEOUT } if (     S  Z) {        S  Z if (  ) { Result result := search(matrix, remaining - 1) if (result == SOLUTION) { return SOLUTION }       if (result == TIMEOUT) { return TIMEOUT } } }          for(   ,    ) {      if (   ) { Result result := search(matrix, remaining - 1) if (result == SOLUTION) { return SOLUTION }       if (result == TIMEOUT) { return TIMEOUT } } } return NO_SOLUTION } 

La matrice d'origine passée à la fonction de recherche est vide, à l'exception de la ligne du bas contenant des blocs de 3 carrés adjacents. Il est transmis avec le nombre de chiffres restants à ajouter. S'il remaining 0, la matrice contient la solution et la fonction retourne. Chaque appel récursif incrémente le nombre global de attempts . S'il dépasse MAX_ATTEMPTS , qui a une valeur de 1 000, la recherche recommence.

La troisiÚme if essaie d'ajouter le tétramino S ou Z au bas de la matrice si l'espace le permet. Cela signifie éviter des situations comme celle illustrée ci-dessous, lorsque l'algorithme passe du temps à remplir une partie de la matrice, ne pouvant pas remplir le reste par manque de support.


GrĂące Ă  l' if elle forme rapidement une plateforme sur laquelle construire:


Pour tenter d'ajouter un chiffre à la matrice, les vérifications ci-dessus sont requises. L'algorithme vérifie si la figure aura un support, étant donné les lignes complétées. Il vérifie également s'il divise par 4 la taille de chaque espace vide individuel créé par l'insertion de la forme.

Conversion d'image


L'algorithme d'imprimante Tetris convertit chaque ligne du bitmap en une sĂ©rie de passes. En se dĂ©plaçant de gauche Ă  droite, chaque passage de maniĂšre "gourmande" insĂšre le tetramino J, T et L Ă  l'endroit oĂč il est placĂ©. Par exemple, l'image ci-dessous montre une ligne de 16 pixels d'une image bitmap.


L'image ci-dessous montre les 5 passes nécessaires pour couvrir ces 16 pixels.






La sĂ©quence de formes que l'algorithme essaie d'insĂ©rer est dĂ©terminĂ©e par les couleurs des pixels. Pour que les formes ne se chevauchent pas, un tableau unidimensionnel de valeurs boolĂ©ennes est utilisĂ©. Pour insĂ©rer une figure, 3 Ă©lĂ©ments zĂ©ro doivent ĂȘtre prĂ©sents dans le tableau. Une fois l'insertion de la figure 3 rĂ©ussie, les Ă©lĂ©ments de tableau correspondants prennent la valeur 1.

Pour suivre les pixels terminés entre plusieurs passes, un deuxiÚme tableau unidimensionnel de valeurs booléennes est utilisé. Lorsque chaque élément vaut 1, la ligne est terminée.

À la fin de chaque passage, le convertisseur d'image recherche dans le tableau tous les motifs pour crĂ©er un ou plusieurs carrĂ©s. À la sortie, il passe le motif correspondant avec le tetramino J, T et L insĂ©rĂ© en bas. Par exemple, le premier passage montrĂ© ci-dessus est affichĂ© comme le motif suivant pour crĂ©er 5 carrĂ©s:


Recherche en temps réel


Le convertisseur d'image dĂ©crit dans la section prĂ©cĂ©dente est extrĂȘmement rapide car il utilise une table constante contenant tous les motifs pour crĂ©er des carrĂ©s et ne les recherche pas en temps rĂ©el. Cependant, la recherche en temps rĂ©el peut utiliser des modĂšles qui ne figurent pas dans le tableau et, par consĂ©quent, rĂ©duire considĂ©rablement la quantitĂ© de tĂ©tramino nĂ©cessaire pour gĂ©nĂ©rer l'image. Il utilise les carrĂ©s crĂ©Ă©s dans les passages prĂ©cĂ©dents, les utilisant comme supports supplĂ©mentaires. Par exemple, comme mentionnĂ© ci-dessus, le modĂšle suivant pour crĂ©er un carrĂ© nĂ©cessite 7 lignes complĂštes.


Mais un carré rouge créé dans le passage précédent dans le coin inférieur gauche de l'image ci-dessous fournit un support supplémentaire, réduisant le nombre de lignes remplies à 3.


De plus, une recherche en temps rĂ©el peut couvrir 3 pixels adjacents de la mĂȘme couleur en retournant le tetramino J, T ou L.


En fait, il peut combiner tĂ©tramino inversĂ© et inversĂ©, couvrant un grand nombre de pixels en une seule passe. Par exemple, les 5 passes ci-dessus nĂ©cessaires pour couvrir 16 pixels peuvent ĂȘtre rĂ©duites Ă  la seule passe illustrĂ©e ci-dessous.


Pour obtenir ce motif, le convertisseur d'image commence par emballer avec enthousiasme le tétramino retourné J, T et L.


Ensuite, il essaie ardemment d'ajouter les versions non retournées, et dans ce cas, il parvient à ajouter un autre J.


En principe, une table de recherche prĂ©-calculĂ©e peut Ă©galement ĂȘtre utilisĂ©e dans ce processus, mais la taille mĂȘme d'une telle table la rend inapplicable dans la pratique.

Dans cet exemple, 8 carrés consécutifs au-dessus de la ligne à créer sont ajoutés à la ligne inférieure de la matrice vide. Pour n carrés sur un terrain de 21 mÚtres carrés, la hauteur de la matrice h est le plus petit entier positif tel que 21h - n est divisible par 4. Dans ce cas, une matrice de hauteur 4 est requise.


La recherche en temps rĂ©el fonctionne exactement de la mĂȘme maniĂšre que l'algorithme de recherche dĂ©crit ci-dessus, mais prĂ©sente des amĂ©liorations mineures. Comme prĂ©cĂ©demment, la pile de colonnes de matrice fournit un support uniquement si la hauteur de colonne moins le nombre de lignes terminĂ©es est supĂ©rieure Ă  zĂ©ro. Lorsque la diffĂ©rence est nulle, la pile de colonnes ne doit pas fournir de support. Cependant, dans cette version, s'il est Ă©gal Ă  zĂ©ro, il vĂ©rifie les carrĂ©s de la ligne crĂ©Ă©e gĂ©nĂ©rĂ©s par les passes prĂ©cĂ©dentes. En d'autres termes, tous les carrĂ©s de la ligne situĂ©e sous la ligne infĂ©rieure de la matrice prennent en charge les colonnes vides.

De plus, la recherche étant effectuée en temps réel, il sera impossible de la rendre exhaustive. S'il n'a pas trouvé de solution aprÚs un certain nombre de tentatives, il ajoute 4 lignes supplémentaires en haut de la matrice, puis réessaye. AprÚs cela, s'il ne pouvait toujours pas trouver de solution aprÚs un certain nombre de tentatives, alors dans le passage en cours, il revient à la méthode avec les tables de recherche précalculées et la conversion d'images décrites dans la section précédente de l'article.

Imprimer


Pour l'impression, vous devez suivre les instructions affichées par le convertisseur d'image sur le terrain de jeu de Tetris. L'imprimante crée un tétramino spécifique au point central supérieur du terrain de jeu dans une orientation standard. Ensuite, l'imprimante la fait pivoter, la déplace horizontalement et l'abaisse. Ce processus est illustré dans la vidéo:


Code source


Le code source du projet Java 7 est disponible ici .

Les algorithmes de recherche pour les tableaux pré-préparés et en temps réel sont dans les packages search.precomputed et search.realtime . Ils utilisent certaines classes communes situées dans le package de search . Les résultats d'une recherche précalculée sont stockés dans le package de patterns sous la forme d'une séquence de fichiers texte. Les fichiers texte stockent les matrices compressées sous forme de caractÚres ASCII, en commençant par A Par exemple, les 3 premiÚres matrices dans emitters1.txt (l'ensemble de modÚles pour créer un carré) ressemblent à ceci:


Comme indiquĂ© Ă  plusieurs reprises dans l'article, 3 symboles A adjacents dans les matrices ci-dessus peuvent ĂȘtre remplacĂ©s par tetramino J, T ou L.Les symboles B , C , D et ainsi de suite reprĂ©sentent la sĂ©quence de tetramino que vous devez crĂ©er.

La classe imageconverter.ImageConverter contient la mĂ©thode main , qui reçoit un seul argument de ligne de commande: le nom du fichier d'image-objet. Une image ne peut pas dĂ©passer 17 × 32 pixels et ne peut pas contenir plus de 3 couleurs opaques. Tous les autres pixels doivent ĂȘtre transparents.

Fait intéressant, dans les anciens jeux vidéo, les développeurs utilisaient souvent l'arriÚre-plan pour obtenir des couleurs supplémentaires. Par exemple, les élÚves et la bouche de Bubble de Bubble bobble, les élÚves de Donkey Kong de Donkey Kong et le sourcil avec la taupe de Miss Pakman de Mme Pac-Man est en fait transparent. Le noir est obtenu à partir d'un fond uni.


Le fond du terrain de jeu de Tetris peut ĂȘtre utilisĂ© de la mĂȘme maniĂšre.

ImageConverter sortie d' ImageConverter ressemble Ă  cet extrait:


Les 3 valeurs hexadécimales de la premiÚre ligne sont 3 couleurs opaques extraites du fichier image sprite. Ils correspondent aux couleurs du tétramino J, T et L. Les couleurs des autres tétramino n'affectent pas l'image. Les blocs restants sont des motifs emballés exécutés sur le terrain de jeu (pour les caractÚres aprÚs Z et jusqu'à a voir le tableau des caractÚres ASCII ). Les blocs jaunes surlignés composent la plateforme. Le premier bloc ajoute la plateforme, le second la supprime.

La classe printer.Printer reçoit un fichier texte dans ce format et génÚre un fichier image en lisant Tetris.

L'algorithme d'imprimante utilisĂ© pour gĂ©nĂ©rer une vidĂ©o ressemblant Ă  la version NES de Tetris dĂ©finit chaque type de tetramino dans chaque bloc d'un fichier texte. Ensuite, il se dĂ©place dans l'ordre opposĂ© du point de dĂ©part et de l'orientation initiale Ă  l'angle de rotation et aux coordonnĂ©es de l'abaissement de la figure indiquĂ©e dans le fichier. Remarque: en raison de la vitesse extrĂȘmement Ă©levĂ©e des chiffres en baisse, il est impossible d'aller au-delĂ  du niveau 30 dans la vraie version NES de Tetris. Il est supposĂ© que l'imprimante transmet toutes ses commandes au terrain de jeu assez rapidement. pour compenser cela.

Pour rĂ©gĂ©nĂ©rer des fichiers de search.precomputed.PatternSearcher , utilisez search.precomputed.PatternSearcher . Il peut ĂȘtre personnalisĂ© en modifiant les constantes au dĂ©but du fichier de code source.

 public static final int MATRIX_WIDTH = 21; public static final int MATRIX_HEIGHT = 4; public static final int EMITTED_SQUARES = 4; public static final int RANDOM_SETS = 100000; public static final int MAX_ATTEMPTS = 1000; 

RANDOM_SETS est le nombre de permutations aléatoires de 371 façons d'ajouter un chiffre à la matrice. Lorsqu'il est défini sur 100000 , il faut plusieurs secondes pour initialiser les permutations au démarrage. De plus, leur stockage nécessite plus d'un gigaoctet de mémoire.

MAX_ATTEMPTS contrÎle le temps d'exécution de la recherche. Une valeur relativement petite de 1000 permet à la recherche de rejeter rapidement les débuts aléatoires qui ne se montrent pas bien. Cependant, afin de prouver que pour une taille de matrice spécifique et le nombre de carrés créés, il n'y a pas de solution, il est nécessaire d'explorer pleinement tout l'espace de recherche. Pour ce faire, vous pouvez définir MAX_ATTEMPTS sur Integer.MAX_VALUE .

Des constantes similaires se trouvent dans search.realtime.RealtimeSearcher , qui est utilisé par le convertisseur d'image. Comme mentionné ci-dessus, une grande valeur RANDOM_SETS nécessite une augmentation de la mémoire maximale et entraßne un démarrage plus long. MAX_RETRIES contrÎle le nombre de tentatives, aprÚs quoi la recherche en temps réel se rend et revient à la recherche avec une table pré-calculée.

Gardez à l'esprit que les deux algorithmes de recherche utilisent 100% du processeur, créant de nombreux threads parallÚles de taille égale au nombre de processeurs disponibles.

Source: https://habr.com/ru/post/fr474848/


All Articles