C# 如何模拟逻辑门和触发器电路

C# 如何模拟逻辑门和触发器电路,c#,wpf,circuit,flip-flop,C#,Wpf,Circuit,Flip Flop,我目前正在学习C#和WPF,我试图模拟一个逻辑门和触发器的电路,但它不起作用 有人能告诉我一个可能的方法来实现这一点吗?(可能是一个简单的类似应用?) 到目前为止,我所尝试的: 类别: public class GateBase { public Type Type { get; set; } public GateBase Input1 { get; set; } public GateBase Input2 { get; se

我目前正在学习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();
                }
            }
        }
    }

// new list
List<Gate> gatesToResetOutputs = new List<Gate>();

while(loop)
{
    while(evaluating gates)
    {
        ...
    }

    while(evaluating flipflops)
    {
        ...
        // instead of
        gate.ResetOutputs();
    
        // replace with
        gatesToResetOutputs.Add(gate);
        ...
    }

    // and at the end of the loop
    foreach(Gate gate in gatesToResetOutputs)
    {
        gate.ResetOutputs();
    }
}
问题:

    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();
                }
            }
        }
    }

// new list
List<Gate> gatesToResetOutputs = new List<Gate>();

while(loop)
{
    while(evaluating gates)
    {
        ...
    }

    while(evaluating flipflops)
    {
        ...
        // instead of
        gate.ResetOutputs();
    
        // replace with
        gatesToResetOutputs.Add(gate);
        ...
    }

    // and at the end of the loop
    foreach(Gate gate in gatesToResetOutputs)
    {
        gate.ResetOutputs();
    }
}
如果我使用的是JK触发器,结果就不符合预期。(但T型触发器工作正常)


这里是解决方案的链接:


谢谢大家!

while循环中的开关盒没有中断,因此如果开关盒是Model.Type.和的话,它会一直下降到Model.Type.XNOR,我假设这不是故意的。这可能是你的问题(或者至少是部分问题)

为了给您一个想法,这个小示例将输出“无中断”。x=3将从默认值输出字符串

using System;

public class Program
{
    public static void Main()
    {
        int x = 1;
        switch(x){
            case 0:
                Console.WriteLine("Break");
                break;
            case 1:
            case 2:
                Console.WriteLine("no break");
                break;
            case 3:
            default:
                Console.WriteLine("End!");
                break;
        }
    }
}
您可以在此处阅读有关传统交换机的更多信息:

现在我修复了一个问题,它比以前工作得好得多。(在更新所有触发器之前,我正在重置门)

但它仍然不能100%正确工作

循环中的更改:

    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();
                }
            }
        }
    }

// new list
List<Gate> gatesToResetOutputs = new List<Gate>();

while(loop)
{
    while(evaluating gates)
    {
        ...
    }

    while(evaluating flipflops)
    {
        ...
        // instead of
        gate.ResetOutputs();
    
        // replace with
        gatesToResetOutputs.Add(gate);
        ...
    }

    // and at the end of the loop
    foreach(Gate gate in gatesToResetOutputs)
    {
        gate.ResetOutputs();
    }
}
//新列表
List gatesToResetOutputs=新列表();
while(循环)
{
while(评估门)
{
...
}
while(评估触发器)
{
...
//而不是
gate.ResetOutputs();
//取代
gatesToResetOutputs.Add(门);
...
}
//在循环的最后
foreach(gatesToResetOutputs中的门)
{
gate.ResetOutputs();
}
}

JL触发器您需要当前状态(值)。我预计切换触发器也会失败。新值基于输入和当前值。我将利用OOP概念简化代码。将您的
GateBase
类拆分为特定的AND、OR、etc门类,并将它们全部从
GateBase
或公共接口继承,以保留将它们放在列表中的可能性。新的类将更加简单和清晰。这将帮助您理解OOP并找到问题:)谢谢您的回答,但实际上这是有意的。我根据输入的数量打开类型(关:开:0输入|出:关:非:1输入|和-XNOR:2输入)