LittleBigPlanet 2の論理回路 (3)
「ORゲート→方向分割ツール」に特殊な挙動を観測したので、信号(Signal構造体)の定義を調整します。「Backward」を追加しました。信号Backwardは、通常、信号Aが負のときtrueとなります。
信号(Backward追加版)
// 信号(デジタルとアナログを含む) struct Signal { // false(オフ), true(オン)。信号の表示上の明暗はこの値で決定される。Dがfalse(オフ/暗いとき)でも、Aが0とは限らない。 public bool D; // 方向分割の出力決定に使う。通常はAが負のときtrue。特別な場合、Aの負号との関係が崩れる。 public bool Backward; public int A; // -100 〜 +100 [%] // DがオフかつAが0%のことを「Signal.Zero」と呼ぶことにする。未接続の入力端子はこの状態。 public static readonly Signal Zero = new Signal(false, 0); // DがオンかつAが100%のことを「Signal.One」と呼ぶことにする。 public static readonly Signal One = new Signal(true, 100); public Signal(bool d, int a) { D = d; A = a; Backward = a < 0; } public Signal(bool d, int a, bool backward) { D = d; A = a; Backward = backward; } // 引数notがtrueのとき、出力Dは、入力Dの否定で、Aの符号は消える。 // falseのとき、値は変化せず、Aの符号も保存される。 public void InvertIf(bool not) { if (not) { D = !D; Backward = !Backward; A = 100 - Math.Abs(A); } } }
方向分割ツール
入力Backwardに応じて、2つの出力端子の片方に出力されます。
// 方向分割ツール // 入力Backwardに応じて、2つの出力の片方に信号を出力(falseのとき+側出力、trueのとき-側出力)する。 // 出力Dは、選択された側のみがtrueとなる。選択された側の出力Aは、入力Aの絶対値となる。 // 選択されていない側の出力は、Signal.Zeroとなる。 public class DirectionSplitter : Logic { public void Update() { Outputs[0] = new Signal(!Inputs[0].Backward, Math.Max(0, Inputs[0].A)); Outputs[1] = new Signal(Inputs[0].Backward, Math.Max(0, -Inputs[0].A)); } }
ANDゲート
2端子以上の入力から、1出力を得ます。
デジタル回路としては、論理積として利用できます。出力Dは、すべての入力がONのときのみ、ONになります。
アナログ回路としては、最小値として利用できます。出力Aは、すべての入力の絶対値のうち最小の入力の絶対値に、入力の負号の数が奇数個のときのみ負号をつけた値になります。
// ANDゲート: 出力Dは論理積として機能する。 // 出力Aは、絶対値が最小の入力Aを選び、その符号は、各入力Aに対して符号関数を適用した結果の積(負号が奇数個のとき負)となる。 // 出力Backwardは通常通り(符号関数を結果の積が負のときtrueとなる)。 public class AndGate : Logic { public bool Inverse; public AndGate() : base(2, 1) { } public void Update() { var d = true; var a = 100; var s = 1; foreach (var input in Inputs) { d &= input.D; a = Math.Min(a, Math.Abs(input.A)); s *= Math.Sign(input.A); } var result = new Signal(d, s * a); result.InvertIf(Inverse); } }
ORゲート
2端子以上の入力から、1出力を得ます。
デジタル回路としては、論理和として利用できます。出力Dは、1つでも入力がONであれば、ONになります。
アナログ回路としては、最小値として利用できます。出力Aは、すべての入力のうち絶対値が最大の入力(同値は若い入力端子が優先)のもとの入力値(符号付き)になります。出力Backwardは、入力0(最も上方の端子)Backwardになります。
// ORゲート: Dは論理和として機能する。 // 出力Aは、絶対値が最大の入力Aを選び(同値は若い入力端子が優先)、その入力Aのもとの値(符号付き)となる。 // 出力Backwardは、入力0(最も上方の端子)Backwardとなる。 public class OrGate : Logic { public bool Inverse; public OrGate() : base(2, 1) { } public void Update() { var d = false; var a = 0; foreach (var input in Inputs) { d |= input.D; if (Math.Abs(input.A) > Math.Abs(a)) a = input.A; } var result = new Signal(d, a, Inputs[0].Backward); result.InvertIf(Inverse); } }
実験した限り、ORゲートの出力Backwardは特殊で、出力Aの符号とは一致しない結果が現れることがありました。DとAでは表せない情報があるとして、「Signal.Backward」を追加しました。