Je veux implémenter un système d'alimentation comme le système Redstone dans Minecraft.
J'ai n sources d'alimentation et m câbles. Si je déconnecte la source d'alimentation ou un câble, le circuit doit s'éteindre.
Comment éviter les cercles? Si chaque câble avec le statut "on" alimente les câbles à proximité, je peux créer des cercles infinis où aucune source d'alimentation n'est impliquée (voir image). Plus le site est qu'il fonctionne en T = m
Je pouvais envoyer une rafale de puissance à travers le graphique à partir de chaque source d'alimentation et à chaque appel de mise à jour, j'éteins chaque câble. Le problème est qu'il s'exécute en T = n * m.
Existe-t-il une meilleure pratique? Dans Minecraft, le système Redstone était très lent, donc je pense que j'ai oublié quelque chose.
EDIT: Le système devrait fonctionner sans décroissance basée sur la distance.
Réponses:
Propagation récursive. Par exemple, vous avez une lampe connectée par N objets de câble à une batterie. La lampe demande au Nième câble s'il est alimenté (c'est le câble relié directement à la lampe). Le Nième câble demande alors au câble N-1 s'il est alimenté et ainsi de suite. Chaque fois qu'un objet est demandé s'il est alimenté ou non, il définit un
lastEvaluated
variable sur la durée d'image actuelle. La récursivité touche un nœud d'extrémité, comme une batterie, ou lorsqu'elle atteint un objet qui a déjà été évalué dans ce cadre (cela évite une récursion infinie). Ces propagations ne se produisent que lorsque le système change. Les changements incluent l'ajout / la suppression de pièces ou de commutateurs basculés.Il n'y a pas de décroissance de distance ou de contraintes similaires avec ce système. Je l'ai utilisé pour créer un simulateur de porte logique et cela fonctionne pour divers exemples logiques comme une bascule.
la source
Dans minecraft, il y a une décroissance basée sur la distance avec une distance de décroissance très courte (plage de 16 blocs).
Ce dont vous avez besoin un test de connectivité entre les graphiques .
Une façon de le faire serait de prendre à plusieurs reprises chaque bord et de combiner les nœuds connectés et en un seul nœud. Une fois que tous les bords ont disparu, vous vous retrouverez avec un nœud pour chaque réseau. L'envoi de puissance est alors insignifiant.
la source
Un bloc alimenté a plusieurs connexions d'entrée / sortie, mais à un point de départ, nous ne savons pas quand il est en entrée ou en sortie.
Chaque bloc a une "tension" qui est l'énergie qui y arrive moins la perte / l'utilisation.
Un bloc alimenté alimentera tous les blocs environnants, et chaque bloc prendra en entrée la tension la plus élevée des blocs environnants. Vous pouvez également compliquer le système en définissant une intensité, mais je ne resterai avec Voltage que pour plus de simplicité.
Chaque fois qu'un changement est effectué sur le circuit, en ajoutant / supprimant des blocs, ou par le circuit lui-même, le changement doit être propagé à tout le circuit jusqu'à la stabilité.
Je vous suggère de concevoir une interface pour tout objet propulsé (cube dans MC):
Supposons donc que vous implémentiez addSibling et removeSibling, la partie la plus importante est la fonction de propagation:
En tant que solution récursive, chaque bloc devrait réduire un peu l'énergie, ne jamais l'augmenter. La source d'énergie peut définir une valeur fixe, mais ne jamais augmenter en fonction des entrées. Cela ne devrait pas être un problème car tous les "vrais" systèmes fonctionnent de cette façon.
la source