I am building a game which allows the player to control "power flow" between 10 circuits.
Each of the 10 circuits is adjusted individually and the total must always equal 100%.
For example a perfectly balanced situation would be all 10 circuits at 10% (10x10=100)
Edit 2: If what I am trying to do here is know as things other than "balancing", please comment and I will research them.
Now the player also has the ability to lock circuits so that the power level cannot be changed by other circuits but it can still be changed directly.
EDIT 3: Sometimes the requested amount may not be possible to achieve (eg: example 3 and 6) in these situations the nearest possible result will be the result
EDIT: Seeing that my post is receiving down votes I will include what I have already tried
To simplify my question we can work with just 5 circuits.
I need assistance to work out the math for calculating the following. After 20 or so attempts I am thinking I am over complicating it as I keep ending up with 200 line scripts or is this actually very complicated?
Example 1: Addition Example
20 20 20 20 20 Start values
+10 +10 0 0 0 Change
30 30 3.3 3.3 3.3 After first iteration
50 50 0 0 0 After x iterations (eg key held down)
Example 2: Subtraction Example
20 20 20 20 20 Start values
-10 -10 0 0 0 Change
10 10 26.6 26.6 26.6 After first iteration
0 0 33.3 33.3 33.3 After x iterations (eg key held down)
Example 3: Lock + Addition (L is locked)
L
2.5 90 2.5 2.5 2.5 Start values
0 0 +50 0 0 Change
0 90 10 0 0 After first iteration
0 90 10 0 0 After x iterations (eg key held down)
Example 4: Lock + Subtraction (L is locked)
L
2.5 90 2.5 2.5 2.5 Start values
0 -10 0 0 0 Change
5 80 5 5 5 After first iteration
25 0 25 25 25 After x iterations (eg key held down)
Example 5: Multi Lock + Subtraction (L is locked)
L L
2.5 90 2.5 2.5 2.5 Start values
0 -10 0 0 0 Change
5.8 80 2.5 5.8 5.8 After first iteration
32.5 0 2.5 32.5 32.5 After x iterations (eg key held down)
Example 6: Balancing change from unbalanced start (This math may be a bit off)
2.5 90 2.5 2.5 2.5 Start values
+10 +10 +10 0 0 Change
16.7 66.6 16.7 0 0 After first iteration
33.3 33.3 33.3 0 0 After x iterations (eg key held down)
Start by retrieving all circuits that may potentially be changed by the runtime:
Candidates = AllCircuits \ (LockedCircuits u ChangedCircuits)
Here, \
denotes the set minus operator and u
is the union operator.
Calculate the average change per circuit:
targetTotalChange = totalChange
averageChange = totalChange / |Candidates|
Now, start to change the candidates. To account for limitations, order the candidates by their current power flow. If averageChange
is negative, then order them in ascending order. If it is positive, order them in descending order.
And remember how many circuits you already have processed:
processedCircuits = 0
Now iterate all candidates in the specified order:
for each candidate in Candidates
Check if the the average change can be added to this circuit. Otherwise, adapt the values:
processedCircuits++
prevPower = candidate.PowerFlow
targetPower = prevPower + averageChange
if(targetPower < 0)
{
totalChange += prevPower
candidate.PowerFlow = 0
//recalculate average change
}
else if(targetPower > 100)
{
totalChange -= 100 - prevPower
candidate.PowerFlow = 100
//recalculate average change
}
else
{
totalChange -= averageChange
candidate.PowerFlow += averageChange
}
When you need to recalculate the average change, do the following:
averageChange = totalChange / (|Candidates| - processedCircuits)
Beware of division by zero.
Now you have adapted all other circuits. What remains is adapting the changed circuits. This is quite easy. We changed all other circuits by targetTotalChange - totalChange
. This change can be added to the changed circuits. We can just add the according percentage:
percentage = (targetTotalChange - totalChange) / targetTotalChange
for each circuit in ChangedCircuits
circuit.PowerFlow += percentage * targetChange[circuit]
next