Inventée par Bob Hyatt, hommage à lui
Application :
Jeux de stratégie sur plateaux, maps.
Principes Généraux :
Elle permet de stocker dans un tableau unidimensionnel (pour faire snob) une matrice habituellement à deux entrées.
Un jeu de plateau ou une map sont généralement constitués de "cases". Les cases de l'echiquier ou l'emplacement des tiles.
L'écran ou le plateau de jeu est composé par la succession de ces cases/tiles.
Origine
----------------------------------------------------->x
| case 1 | case 2 | case 3 | case 4 | case 5|
| (0,0) | (1,0) | (2,0) | (3,0) | (4,0) |
|------------------------------------------------------
| case 6 | case 7 | case 8 | case 9 | case10|
| (0,1) | (1,1) | (2,1) | (3,1) | (4,1) |
|------------------------------------------------------
| case11 | case 12 | case 13| case14 | case 15|
| (0,2) | (1,2) | (2,2) | (3,2) | (4,2) |
|------------------------------------------------------
| case 16 | case 17 | case 18| case 19|case 20|
| (0,3) | (1,3) | (2,3) | (3,3) | (4,3) |
|------------------------------------------------------
| case 21 | case 22 | case 23 |case 24 |case 25|
| (0,4) | (1,4) | (2,4) | (3,4) | (4,4) |
|------------------------------------------------------
V
Y
Pour représenter l'échiquier, on peut travailler sur les coordonnées pures x et y.
Mais on imaginera volontiers l'utilisation d'un tableau à 2 dimensions, la 1ère correspondant à la position sur la ligne, la seconde à la position sur la colonne.
Ainsi pour reprendre l'exemple si dessus.
Soit un tableau Mon_echiquier(ligne,colonne).
La case 1 correspond à Mon_echiquier(0,0).
La case 2 à Mon_echiquier(1,0).
La case 7 à Mon_echiquier(1,1).
La Section Data ressemblerait à ça :
Code : Tout sélectionner
Data.b 0,0 1,0 2,0 3,0 4,0
Data.b 0,1 1,1 2,1 3,1 4,1
Data.b 0,2 1,2 2,2 3,2 4,2
Data.b 0,3 1,3 2,3 3,3 4,3
Data.b 0,4 1,4 2,4 3,4 4,4
Ainsi un déplacement d'une case à droite équivaut à [+1,+0].
Un déplacement de deux cases vers le haut équivaut [+0,-2].
Une diagonale d'une case, vers le haut et la gauche à [-1,-1].
Très logique en fin de compte……mais très vite complexe à manipuler à l'usage et source d'erreurs. Sans compter qu'un tableau à 2 dimensions consomme plus de ressources qu'un tableau à entrée unique (même si cet argument prévaut moins à l'heure de nos PC flambants- sauf le mien…-).
L'alternative : un tableau unidimensionnel.
Avec cette astuce, le même echiquier (ou map) peut être stocké dans un tableau à entrée unique.
On n' appréhende plus la case de cette façon :
Mon_echiquier(position_sur_la_ligne,position_sur_la_colonne)
Mais :
Mon_echiquier(index de la case).
Origine
-----------------------------------------------------x
| case 1 | case 2 | case 3 | case 4 | case 5|
| (0) | (1) | (2) | (3) | (4) |
|------------------------------------------------------
| case 6 | case 7 | case 8 | case 9 | case10|
| (5) | (6) | (7) | (8) | (9) |
|------------------------------------------------------
| case11 | case 12 | case 13| case14 | case 15|
| (10) | (11) | (12) | (13) | (14) |
|------------------------------------------------------
| case 16 | case 17 | case 18| case 19|case 20|
| (15) | (16) | (17) | (18) | (19) |
|------------------------------------------------------
| case 21 | case 22 | case 23 |case 24 |case 25|
| (20) | (21) | (22) | (23) | (24) |
|------------------------------------------------------
V
Y
L'accès aux cases est d'autant plus facile puisqu'il suffit de connaître un index et non plus deux vecteurs.
La DataSection serait alors simplement :
Code : Tout sélectionner
Data.b 0 , 1 , 2 , 3, 4
Data.b 5 , 6 , 7 , 8, 9
Data.b 10,11,12,13,14
Data.b 15,16,17,18,19
Data.b 20,21,22,23,24
La gestion des déplacements :
On retrouve les mêmes règles logiques, en plus simple :
Pour aller sur la case de droite ? Index+1
La case de gauche ? Index –1
En haut ? Dans le cas ci-dessus index –5
En diagonale Bas gauche ? Index +4.
Oui mais………
Il existe des déplacements aberrants :
Si je suis sur la case 5 et que je me déplace d'une case à droite selon la méthode décrite plus haut, je sors du plateau de jeu (cf schema plus haut). Pourtant le programme lui me renverrait que ma pièce ou mon sprite atterrit …sur la case 6 ??!! Aberrant !!!
Il nous faut donc prendre en charge ces exceptions.
Et rassurez vous c'est tout bête grâce à la technique mail box !
Vous avez du courrier :
La solution consiste à utiliser un tableau que j'appellerai "tableau de transposition" (ne décrochez pas, ce n'est pas si complexe).
On utilise la valeur –1 pour marquer les exceptions.
Voici mon nouveau data section :
Data.b -1, -1, -1, -1, -1, -1, -1 ;
Data.b -1, -1, -1, -1, -1, -1, -1 ;
Data.b -1, 1, 2, 3, 4, 5, -1 ;
Data.b -1, 6, 7, 8, 9,10, -1 ;
Data.b -1,11, 12, 13,14,15, -1 ;
Data.b -1,16, 17, 18,19,20, -1 ;
Data.b -1,21, 22, 23,24,25, -1 ;
Data.b -1, -1, -1, -1, -1, -1, -1 ;
Data.b -1, -1, -1, -1, -1, -1, -1 ;
(Pour l'histoire, ceci ressemblerait à une boîte à lettres, d'où le nom de la technique).
Nous appellerons ce tableau MailBox() (mais vous pouvez choisir cde l'appeler LadyDi si vous préféreez)
Notez qu’au milieu de tous ces « -1 » on retouve la structure de notre echiquier avec nos cases de 1 à 25 (Attention à votre définition du point de départ, 0 ou 1. Une source d'erreur très fréquente).
Il nous reste à reprendre le tableau de 5x5 qui représente notre echiquier près transposition au moyen de la boite aux lettres.
Code : Tout sélectionner
Data.b 15, 16, 17, 18, 19
Data.b 22, 23, 24, 25, 26
Data.b 29, 30, 31, 32, 33
Data.b 36, 37, 38, 39, 40
Data.b 43, 44, 45, 46, 47
Dans la boîte aux lettres, le 15ème élément à la valeur 1. La numérotation de nos cases commence donc à 15.
La case 23 correspond elle au 46ème élément de la boîte aux lettres.
Etc.… Vous avez pigé le truc.
Oui mais à quoi ça sert ?
Reprenons notre exemple de "déplacement impossible".
La pièce sur la case 5 ne peut pas se déplacer à droite car elle a atteint le bout de l'échiquier.
On va donc interroger Mailbox(mon_echiquier(19+1)). [Rappel la 5ème case vaut 19 comme on vient de le voir].Autrement dit, quelle valeur me renvoie l'élément du tableau Mailbox à la position ma_case+1
Que constate-t-on ? Que MailBox(20)= -1 !! Le déplacement est impossible !
Autre exemple :
On va considérer un coup qui lui est autorisé.
Aller de la case 12 à la case 7. Soit un déplacement de 1 case en haut.
Que renvoie mailbox(mon_echiquier(30-7)) ? 7 !
Le coup est bien légal car la valeur renvoyée est bien celle de la case d'arrivée !
Essayez d’autres cas de figures pour vous en convaincre.
Conclusion :
Vous voyez tout l'intérêt de cette méthode pour la manipulation de ce type de données.
Je vous assure qu’on gagne un temps monstrueux ! La seule difficulté consiste à établir la boîte mail et transposer les valeurs (là il ne faut pas se louper). Mais vous le faites une fois pour toutes et après la marge d’erreur est nulle !!
J'espère ne pas avoir été trop rébarbatif et que ce tuto vous aura accroché jusqu'au bout.
Désolé aussi pour les schémas et les datasections qui sont pas super bien alignés au final...
J'ai poussé les exemples dans le champs qui m'intéressait personnellement (les jeux de plateaux) mais les applications ne se limitent évidemment pas à ce genre.
N'hésitez pas à m'interroger sur le sujet, j'ai eu l'occasion de bien en faire le tour avec mon PureMarel.