Add branch-aware junction flow
This commit is contained in:
59
src/ReactorMaintenance.Simulation/JunctionFlow.cs
Normal file
59
src/ReactorMaintenance.Simulation/JunctionFlow.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
namespace ReactorMaintenance.Simulation;
|
||||
|
||||
public sealed record JunctionFlow
|
||||
{
|
||||
public GridPosition Position { get; init; } = new(0, 0);
|
||||
public PropState Prop { get; init; } = new();
|
||||
public ECarrierType Carrier { get; init; }
|
||||
public IReadOnlyList<GridPosition> Branches { get; init; } = Array.Empty<GridPosition>();
|
||||
public GridPosition? IncomingBranch { get; init; }
|
||||
public IReadOnlyList<GridPosition> OutgoingBranches { get; init; } = Array.Empty<GridPosition>();
|
||||
public IReadOnlyList<string> Errors { get; init; } = Array.Empty<string>();
|
||||
public bool IsValid => Errors.Count == 0;
|
||||
|
||||
public float WeightFor(GridPosition outgoingBranch)
|
||||
{
|
||||
var index = IndexOfOutgoingBranch(outgoingBranch);
|
||||
if (index < 0)
|
||||
return 0;
|
||||
|
||||
var weights = Prop.Type == EPropType.TJunction
|
||||
? TJunctionWeights(Prop.TJunctionMode)
|
||||
: CrossJunctionWeights(Prop.CrossJunctionMode);
|
||||
return index < weights.Length ? weights[index] : 0;
|
||||
}
|
||||
|
||||
private int IndexOfOutgoingBranch(GridPosition outgoingBranch)
|
||||
{
|
||||
for (var i = 0; i < OutgoingBranches.Count; i++)
|
||||
{
|
||||
if (OutgoingBranches[i] == outgoingBranch)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
private static float[] TJunctionWeights(ETJunctionMode mode)
|
||||
{
|
||||
return mode switch {
|
||||
ETJunctionMode.ZeroFour => [0, 1],
|
||||
ETJunctionMode.OneThree => [0.25f, 0.75f],
|
||||
ETJunctionMode.TwoTwo => [0.5f, 0.5f],
|
||||
ETJunctionMode.ThreeOne => [0.75f, 0.25f],
|
||||
ETJunctionMode.FourZero => [1, 0],
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(mode), mode, "Unsupported T-junction mode.")
|
||||
};
|
||||
}
|
||||
|
||||
private static float[] CrossJunctionWeights(ECrossJunctionMode mode)
|
||||
{
|
||||
return mode switch {
|
||||
ECrossJunctionMode.ZeroThreeThree => [0, 0.5f, 0.5f],
|
||||
ECrossJunctionMode.ThreeZeroThree => [0.5f, 0, 0.5f],
|
||||
ECrossJunctionMode.ThreeThreeZero => [0.5f, 0.5f, 0],
|
||||
ECrossJunctionMode.TwoTwoTwo => [1f / 3f, 1f / 3f, 1f / 3f],
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(mode), mode, "Unsupported cross-junction mode.")
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user