Quiero implementar un sistema de energía como el sistema Redstone en Minecraft.
Tengo n fuentes de alimentación ym cables. Si desconecto la fuente de alimentación o un cable, el circuito debería apagarse.
¿Cómo evito los círculos? Si cada cable con el estado "encendido" alimenta los cables cercanos, puedo crear círculos infinitos donde no hay una fuente de energía involucrada (ver imagen). El sitio más es que se ejecuta en T = m
Podría enviar una ráfaga de energía a través del gráfico comenzando en cada fuente de energía y en cada llamada de actualización apago todos los cables. El problema es que se ejecuta en T = n * m.
¿Hay una mejor práctica? En Minecraft, el sistema de redstone era muy lento, así que creo que pasé por alto algo.
EDITAR: El sistema debería funcionar sin una desintegración basada en la distancia.
Respuestas:
Propagación recursiva. Por ejemplo, tiene una lámpara conectada por N objetos de cable a una batería. La lámpara le pregunta al enésimo cable si está alimentado (este es el cable conectado directamente a la lámpara). El enésimo cable le pregunta al cable N-1 si está encendido y así sucesivamente. Cada vez que se le pregunta a un objeto si está alimentado o no, establece una
lastEvaluated
variable al tiempo de cuadro actual. La recursión toca fondo en un nodo final, como una batería, o cuando alcanza un objeto que ya ha sido evaluado ese marco (esto evita una recursión infinita). Estas propagaciones solo ocurren cuando el sistema cambia. Los cambios incluyen agregar / quitar partes o interruptores que se alternan.No hay disminución de distancia o restricciones similares con este sistema. Lo utilicé para crear un simulador de puerta lógica y funciona para varios ejemplos lógicos como un flip-flop.
fuente
En Minecraft hay una desintegración basada en la distancia con una distancia de desintegración muy corta (rango de 16 bloques).
Lo que necesitas es una prueba de conectividad entre gráficos .
Una forma de hacerlo sería tomar repetidamente cada borde y combinar los nodos conectados en un solo nodo. Después de que todos los bordes se hayan ido, terminará con un nodo para cada red. Entonces enviar poder es trivial.
fuente
Un bloque alimentado tiene varias conexiones de entrada / salida, pero en un punto de partida, no sabemos cuándo es entrada o salida.
Cada bloque tiene un "Voltaje", que es la energía que llega a él menos la pérdida / uso.
Un bloque alimentado proporcionará energía a todos los bloques circundantes, y cada bloque toma como entrada el voltaje más alto de los bloques circundantes. También podría complicar el sistema definiendo una Intensidad, pero me quedaré con Voltaje solo por simplicidad.
Cada vez que se realiza un cambio en el circuito, agregando / quitando bloques, o por el circuito en sí, el cambio debe propagarse a todo el circuito hasta la estabilidad.
Te sugiero que diseñes una interfaz para cualquier objeto alimentado (cubo en MC):
Entonces, suponiendo que implemente addSibling y removeSibling, la parte más importante es la función de propagación:
Como solución recursiva, cada bloque debe reducir un poco la energía, nunca aumentarla. La fuente de energía puede establecer un valor fijo, pero nunca aumentar según las entradas. Eso no debería ser un problema ya que todos los sistemas "reales" funcionan de esta manera.
fuente