【发布时间】:2021-07-06 20:47:04
【问题描述】:
我目前正在学习 C# 和 WPF,我正在尝试模拟逻辑门和触发器的电路,但它不起作用。
有人可以告诉我实现这一目标的可能方法吗? (也许是一个简单的类似应用程序?)
到目前为止我所尝试的:
类:
public class GateBase
{
public Type Type { get; set; }
public GateBase Input1 { get; set; }
public GateBase Input2 { get; set; }
public List<GateBase> Outputs { get; set; }
public bool Evaluated { get; set; }
public bool Value { get; set; }
public bool FlipFlop { get; set; }
public GateBase(Type type = Type.OFF, Gate input1 = null, Gate input2 = null)
{
Type = type;
Input1 = input1;
Input2 = input2;
Outputs = new List<GateBase>();
Evaluated = false;
Value = false;
FlipFlop = false;
switch (Type)
{
case Type.T:
case Type.D:
case Type.SR:
case Type.JK: FlipFlop = true; break;
}
}
public bool Evaluate()
{
if (!Evaluated)
{
bool input1 = false;
bool input2 = false;
if (Input1 != null)
{
if (Input1.FlipFlop)
input1 = Input1.Value;
else
input1 = Input1.Evaluate();
}
if (Input2 != null)
{
if (Input2.FlipFlop)
input2 = Input2.Value;
else
input2 = Input2.Evaluate();
}
switch (Type)
{
case Type.OFF:
Value = false; break;
case Type.ON:
Value = true; break;
case Type.OUT:
Value = input1; break;
case Type.CON:
Value = input1; break;
case Type.NOT:
Value = input1; break;
case Type.AND:
Value = input1 & input2; break;
case Type.OR:
Value = input1 | input2; break;
case Type.XOR:
Value = input1 ^ input2; break;
case Type.NAND:
Value = !(input1 & input2); break;
case Type.NOR:
Value = !(input1 | input2); break;
case Type.XNOR:
Value = !(input1 ^ input2); break;
case Type.D:
Value = input1; break;
case Type.T:
Value = input1 ? Value : !Value; break;
case Type.SR:
Value = (input1 ^ input2) ? Value : Value; break;
case Type.JK:
Value = (input1 ^ input2) ? input1 : (input1 & input2) ? !Value : Value; break;
default: Value = false; break;
}
}
Evaluated = true;
return Value;
}
public void ResetOutputs()
{
Evaluated = false;
foreach (Gate gate in Outputs)
{
if(!gate.FlipFlop)
{
gate.ResetOutputs();
}
}
}
}
循环:
- 更新所有逻辑门
- 更新所有触发器并取消评估每个触发器的输出(如果它们不是触发器)
public List<GateBase> Gates { get; set; }
while (loop)
{
bool evaluating = true;
while (evaluating)
{
evaluating = false;
foreach (Gate gate in Gates)
{
switch (gate.Type)
{
case Model.Type.ON:
case Model.Type.OFF:
gate.Value = gate.Evaluate();
break;
case Model.Type.OUT:
case Model.Type.CON:
case Model.Type.NOT:
if (gate.Input1 != null && (gate.Input1.Evaluated || gate.Input1.FlipFlop))
{
gate.Value = gate.Evaluate();
}
break;
case Model.Type.AND:
case Model.Type.OR:
case Model.Type.XOR:
case Model.Type.NAND:
case Model.Type.NOR:
case Model.Type.XNOR:
if (gate.Input1 != null && gate.Input2 != null)
{
if ((gate.Input1.Evaluated || gate.Input1.FlipFlop) && (gate.Input2.Evaluated || gate.Input2.FlipFlop))
{
gate.Value = gate.Evaluate();
}
}
else
{
evaluating = true;
}
break;
}
}
}
evaluating = true;
while (evaluating)
{
evaluating = false;
foreach (Gate gate in Gates)
{
switch (gate.Type)
{
case Model.Type.D:
case Model.Type.T:
if (gate.Input1 != null && (gate.Input1.Evaluated || gate.Input1.FlipFlop))
{
gate.Value = gate.Evaluate();
gate.ResetOutputs();
}
else
{
evaluating = true;
}
break;
case Model.Type.SR:
case Model.Type.JK:
if (gate.Input1 != null && gate.Input2 != null)
{
if ((gate.Input1.Evaluated || gate.Input1.FlipFlop) && (gate.Input2.Evaluated || gate.Input2.FlipFlop))
{
gate.Value = gate.Evaluate();
gate.ResetOutputs();
}
}
else
{
evaluating = true;
}
break;
}
}
}
}
问题:
如果我使用的是 JK 触发器,结果将不符合预期。 (但 T 型触发器工作正常)
这里是解决方案的链接:Solution on GitHub
谢谢!
【问题讨论】:
-
JL 人字拖需要当前状态(值)。我预计切换触发器也失败了。新值基于输入和当前值。
-
我会通过利用 OOP 概念来简化代码。将您的
GateBase类拆分为特定的 AND、OR 等门类,并从GateBase或通用接口继承它们,以保持将它们放在您的列表中的可能性。新的类会更简单、更清晰。这将帮助您了解 OOP 并找到问题所在:)