16/06/2021
| Modifié le :12/07/2021
| Statut :Terminé
Créé le 10 juin 2021 pour le jeu "Alternia".
Mon objectif pour ce projet était de réaliser un algorithme viable permettant de positionner les noeuds d'un arbre de données de façon intelligible en une seule traversée, afin de simplifier le rendu de l'arbre de compétences du jeu "Alternia" tout en réduisant au maximum le coût en ressources de ce processus.
La fonction nécessite au moins 3 paramètres :
ainsi qu'un moyen de stocker la position horizontale la plus à droite pour chaque niveau de profondeur (un dictionnaire utilisant la profondeur comme clé par exemple).
Pour pouvoir effectuer une seule traversée de l'arbre sans perdre en simplicité, on effectue une traversée en post-ordre (enfants puis racine).
Si le nombre d'enfants du noeud actuel est supérieur à zéro :
Sinon, si la dernière position horizontale pour la profondeur actuelle est définie et la position horizontale reçue en paramètre est inférieure à cette dernière : on définit la position horizontale cible à la dernière position horizontale pour la profondeur actuelle.
Sinon, si la dernière position horizontale pour la profondeur précédente (profondeur actuelle - 1) est définie et la position horizontale reçue en paramètre est inférieure à cette dernière : on définit la position horizontale cible à la dernière position horizontale pour la profondeur précédente.
Pour finir, on définit la dernière position horizontale pour la profondeur actuelle ainsi que la position horizontale du noeud actuelle à la position horizontale cible et la position verticale à la profondeur actuelle multipliée par la hauteur d'un noeud.
Pour faciliter la compréhension de ce dernier, j'ai également réalisé un exemple d'utilisation en python (le jeu est codé en C# mais j'ai choisi le python pour l'exemple pour sa simplicité de lecture et de transposition dans un autre langage).
Dictionary<int, float> lastXAtDepth
FUNCTION Instantiate(node, xPosition = 0, depth)
IF depth < 0 THEN
RAISE EXCEPTION : Depth shouldn't be negative
END IF
IF node.childCount > 0 THEN
FOR i IN range(0, node.childCount) DO
child = node.children[i]
IF i > 0 AND child.childCount > 1 AND node.children[i - 1].childCount EQUALS 0 THEN
xPosition = node.children[i - 1].xPosition
ELSE IF lastXAtDepth CONTAINS KEY depth + 1 AND xPosition < lastXAtDepth[depth + 1] + child.width
xPosition = lastXAtDepth[depth + 1] + child.width
END IF
Instantiate(child, xPosition, depth + 1)
END FOR
minX = node.children[0].xPosition
maxX = node.children[node.childCount - 1].xPosition
xPosition = (minX + maxX) / 2
ELSE IF lastXAtDepth CONTAINS KEY depth AND xPosition < lastXAtDepth[depth] THEN
xPosition = lastXAtDepth[depth]
ELSE IF lastXAtDepth CONTAINS KEY depth - 1 AND xPosition < lastXAtDepth[depth - 1] THEN
xPosition = lastXAtDepth[depth - 1]
END IF
lastXAtDepth(depth) = xPosition
node.xPosition = xPosition
node.yPosition = depth * nodeHeight
END FUNCTION
Lors de la création de ce projet, j'ai été amené à réaliser un algorithme facile à faire évoluer et à utiliser en prenant en compte des limitations techniques précises. Cet exercice m'a permis d'améliorer mes capacités d'analyse et de résolution de problème ainsi que d'optimisation pouvant s'avérer indispensables durant le développement d'une application.
Libre à vous d'utiliser cet algorithme comme bon vous semble et d'y apporter votre touche personnelle tant que vous pensez à me créditer !
Unity, C#, Algorithme, Programmation UI
Vu 630 fois