Um bloco energizado possui várias conexões de entrada / saída, mas, no ponto inicial, não sabemos quando é entrada ou saída.
Cada bloco possui uma "Voltagem", que é a energia que chega a ele menos os perdidos / usados.
Um bloco energizado fornecerá energia a todos os blocos circundantes e cada bloco terá como entrada a tensão mais alta dos blocos circundantes. Você também pode complicar o sistema definindo uma intensidade, mas ficarei com a tensão apenas por simplicidade.
Toda vez que uma alteração é realizada no circuito, adicionando / removendo blocos, ou pelo próprio circuito, a alteração precisa ser propagada para todo o circuito até a estabilidade.
Eu sugiro que você crie uma interface para qualquer objeto energizado (cubo no MC):
class PowerInterface
{
protected:
std::vector<shared_ptr<PowerInterface>> sibling;
double energy=0;
bool isActive = false;
virtual void propagate(double inEnergy) = 0;
virtual void addSibling(shared_ptr<PowerInterface> newSibling) = 0;
virtual void removeSibling( shared_ptr<PowerInterface> remSibling) =0;
};
Portanto, supondo que você implemente os addSibling e removeSibling, a parte mais importante é a função de propagação:
void PoweredCube::propagate( double inEnergy )
{
// Define the behaviour
energy = inEnergy-1.0; // Normal device
energy = inEnergy-0.1; // Normal cable
energy = 10.0; // Normal source of power.
if (energy<0.0)
{
energy = 0.0;
isActive = false;
// No energy, so do not propagate anymore
return;
}
isActive = true;
// Propagate
for (auto &s: sibling)
{
// Only propagate to sibling with less energy.
if (energy > s->energy) s->propagate( energy);
}
}
Como solução recursiva, cada bloco deve reduzir um pouco a energia, nunca aumentá-la. A fonte de energia pode definir um valor fixo, mas nunca aumenta com base nas entradas. Isso não deve ser um problema, pois todo sistema "real" funciona dessa maneira.