/// <summary> /// Constructs a Circuit given a Dictionary of all the gates, /// List of all outputs, and List of all inputs /// </summary> public Circuit(Dictionary <Sketch.Shape, Dictionary <int, Tuple <Shape, int> > > shapesAndTheirInputs, List <Shape> outputs, List <Shape> inputs, Dictionary <Sketch.Shape, CircuitElement> subCircuits) : this() { // Build global inputs foreach (Shape inputShape in inputs) { INPUT input = new INPUT(inputShape.Name, inputShape.Bounds, inputShape.Orientation); shapesToElements.Add(inputShape, input); globalInputs.Add(input); } // Build global outputs foreach (Shape outputShape in outputs) { OUTPUT output = new OUTPUT(outputShape.Name, outputShape.Bounds); shapesToElements.Add(outputShape, output); globalOutputs.Add(output); } // Build logic gates within the circuit foreach (var shapeAndInputs in shapesAndTheirInputs) { Shape gateShape = shapeAndInputs.Key; Gate gateElement; // If the shape is not a gate, or is already in the circuit, skip it. if (!LogicDomain.IsGate(gateShape.Type) || shapesToElements.ContainsKey(gateShape)) { continue; } // If it's a subcircuit, roll our own circuit element. else if (subCircuits.Keys.Contains(gateShape)) { SubCircuit associatedSub = (SubCircuit)subCircuits[gateShape]; associatedSub = new SubCircuit(gateShape.Name, gateShape.Bounds, gateShape, associatedSub.inputs, associatedSub.outputs, associatedSub.behavior, gateShape.Orientation); gateElement = associatedSub; subCircuits[gateShape] = associatedSub; } // Otherwise, create an element normally. else { gateElement = createGate(gateShape.Name, gateShape.Bounds, gateShape.Orientation, gateShape.Type); } if (gateElement == null) { throw new Exception("failed to create gate!"); } shapesToElements.Add(gateShape, gateElement); gates.Add(gateElement); } connectEverything(shapesAndTheirInputs); }
/// <summary> /// check to see if if the inputs and outputs for any subcircuits are consistent, and raise /// ParseErrors if they are not /// </summary> /// <returns></returns> private bool CheckSubcircuits(Circuit circuit) { bool valid = true; if (circuit == null) { throw new ArgumentNullException(); } foreach (CircuitSimLib.Gate gate in circuit.AllGates) { if (gate.GateType == LogicDomain.SUBCIRCUIT) { CircuitSimLib.SubCircuit subCircuit = ((CircuitSimLib.SubCircuit)gate); if (gate.InputPorts.Count != subCircuit.inputsRequired) { valid = false; _parseErrors.Add(new ParseError("The Subcircuit " + gate.Name + " needs " + subCircuit.inputsRequired + " inputs, but has " + gate.InputPorts.Count, "The Subcircuit " + gate.Name + " needs " + subCircuit.inputsRequired + " inputs, but has " + gate.InputPorts.Count, subCircuit.shape)); } if (gate.Outputs.Count != subCircuit.outputsRequired) { valid = false; _parseErrors.Add(new ParseError("The Subcircuit " + gate.Name + " needs " + subCircuit.outputsRequired + " outputs, but has " + gate.Outputs.Count, "The Subcircuit " + gate.Name + " needs " + subCircuit.outputsRequired + " outputs, but has " + gate.Outputs.Count, subCircuit.shape)); } } } return(valid); }
/// <summary> /// Constructs a Circuit given a Dictionary of all the gates, /// List of all outputs, and List of all inputs /// </summary> /// <param name="dictionary"></param> /// <param name="outputs"></param> /// <param name="inputs"></param> public Circuit(Dictionary <string, Data.Pair <Sketch.Shape, Dictionary <string, int> > > dictionary, Dictionary <string, Data.Pair <Sketch.Shape, Data.Pair <string, int> > > outputs, Dictionary <string, Sketch.Shape> inputs) { if (debug) { string gates = "Gates: "; foreach (string gate in dictionary.Keys) { gates += gate + " "; } string instring = "Inputs: "; foreach (string inp in inputs.Keys) { instring += inp + " "; } string outstring = "Outputs: "; foreach (string outp in outputs.Keys) { outstring += outp + " "; } Console.WriteLine(gates); Console.WriteLine(instring); Console.WriteLine(outstring); } globalInputs = new List <INPUT>(); myGates = new List <Gate>(); globalOutputs = new List <OUTPUT>(); namesToElements = new Dictionary <string, CircuitElement>(); outputValues = new Dictionary <string, int>(); isOscillating = false; // Builds global inputs foreach (string inputName in inputs.Keys) { INPUT input = new INPUT(inputName, inputs[inputName].Bounds, inputs[inputName].Orientation); namesToElements.Add(inputName, input); globalInputs.Add(input); } // Builds logic gates within the circuit foreach (string gateName in dictionary.Keys) { Gate tempGate = null; Rect bounds = dictionary[gateName].A.Bounds; double orientation = dictionary[gateName].A.Orientation; ShapeType type = dictionary[gateName].A.Type; if (type == LogicDomain.AND) { tempGate = new AND(gateName, bounds, orientation); } else if (type == LogicDomain.NAND) { tempGate = new NAND(gateName, bounds, orientation); } else if (type == LogicDomain.OR) { tempGate = new OR(gateName, bounds, orientation); } else if (type == LogicDomain.NOR) { tempGate = new NOR(gateName, bounds, orientation); } else if (type == LogicDomain.XOR) { tempGate = new XOR(gateName, bounds, orientation); } else if (type == LogicDomain.XNOR) { tempGate = new XNOR(gateName, bounds, orientation); } else if (type == LogicDomain.NOT) { tempGate = new NOT(gateName, bounds, orientation); } else if (type == LogicDomain.NOTBUBBLE) { tempGate = new NOTBUBBLE(gateName, bounds, orientation); } else if (type == LogicDomain.SUBCIRCUIT) { tempGate = new SubCircuit(gateName, bounds, dictionary[gateName].A, orientation); } else if (type == LogicDomain.FULLADDER) { tempGate = new Adder(gateName, bounds, orientation); } else if (type == LogicDomain.SUBTRACTOR) { tempGate = new Subtractor(gateName, bounds, orientation); } if (tempGate != null) { namesToElements.Add(gateName, tempGate); myGates.Add(tempGate); } } // Connect all CircuitElements foreach (string gateName in dictionary.Keys) { foreach (string inputName in dictionary[gateName].B.Keys) { namesToElements[gateName].addChild(namesToElements[inputName], dictionary[gateName].B[inputName]); } } //builds and connects all global Outputs foreach (string gate in outputs.Keys) { OUTPUT output = new OUTPUT(gate, outputs[gate].A.Bounds, namesToElements[outputs[gate].B.A]); output.addChild(namesToElements[outputs[gate].B.A], outputs[gate].B.B); namesToElements.Add(gate, output); globalOutputs.Add(output); } numInputs = globalInputs.Count; //This part of the code (until the end of the constructor) recognizes whether if the drawn diagram contains more than one circuit. List <KeyValuePair <OUTPUT, List <INPUT> > > tempList = new List <KeyValuePair <OUTPUT, List <INPUT> > >(); circuitList = new List <List <OUTPUT> >(); foreach (OUTPUT output in globalOutputs) { List <INPUT> lis = findGlobalInputs(output); KeyValuePair <OUTPUT, List <INPUT> > k = new KeyValuePair <OUTPUT, List <INPUT> >(output, lis); tempList.Add(k); } for (int i = 0; i < tempList.Count; i++) { List <OUTPUT> outputList = new List <OUTPUT>(); outputList.Add(tempList[i].Key); for (int j = 0; j < tempList.Count; j++) { if (i != j) { bool intersect = Check(tempList[i].Value, tempList[j].Value); if (intersect) { outputList.Add(tempList[j].Key); } } } bool newCircuit = true; foreach (List <OUTPUT> subCircuit in circuitList) { if (Check(subCircuit, outputList)) { newCircuit = false; } } if (newCircuit) { circuitList.Add(outputList); } } }