using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Media; using System.Xml.Linq; using System.Windows; namespace HradlovaSit { /// /// abstraktni trida, kterou dedi vsechny komponenty site vcetne site samotne /// public abstract class BaseComponent { public BaseComponent() { Inputs = new Dictionary(); Outputs = new Dictionary(); } /// /// vyhodnoti data na komponente /// /// public abstract bool Evaluate(); /// /// vstupy komponenty /// public virtual Dictionary Inputs { get; set; } /// /// vystupy komponenty /// public virtual Dictionary Outputs { get; set; } public abstract Drawing Draw();//TODO... /// /// nacte komponentu z XML elementu /// public abstract bool LoadFromXML(XElement elem); public abstract XElement SaveToXML();//TODO... public virtual Rect Bounds { get; set; } public virtual Net BaseNet { get; set; } /// /// kolik vstupu ma jiz prirazenou hodnotu /// public virtual int InputsSet { get; set; } /// /// nacte z atributu elementu rozmery a pozici /// /// /// protected bool LoadBounds(XElement elem) { foreach (var a in elem.Attributes()) { string n = a.Name.LocalName.ToLower(); if (n == "x") { int v; if (!int.TryParse(a.Value, out v)) return false; this.Bounds = new Rect(v, this.Bounds.Y, this.Bounds.Width, this.Bounds.Height); } else if (n == "y") { int v; if (!int.TryParse(a.Value, out v)) return false; this.Bounds = new Rect(this.Bounds.X, v, this.Bounds.Width, this.Bounds.Height); } else if (n == "w") { int v; if (!int.TryParse(a.Value, out v)) return false; this.Bounds = new Rect(this.Bounds.X, this.Bounds.Y, v, this.Bounds.Height); } else if (n == "h") { int v; if (!int.TryParse(a.Value, out v)) return false; this.Bounds = new Rect(this.Bounds.X, this.Bounds.Y, this.Bounds.Width, v); } } return true; } } /// /// reprezentuje celou sit /// public class Net : BaseComponent { public Dictionary Components = new Dictionary(); public List AllInputs = new List(), AllOutputs = new List(); /// /// Jednotlive hodnoty komponent podle ID /// //public Dictionary ValuesDictionary = new Dictionary(); private List inputsOrder = new List(), outputsOrder = new List(); /// /// nacte vstupy site z retezce ve spravnem poradi /// /// /// public bool InsertInputs(string inputs) { for (int i = 0; i < inputsOrder.Count; i++) { if (i >= inputs.Length) return false; bool v = true; if (inputs[i] == '0') v = false; else if (inputs[i] != '1') return false; this.Inputs[inputsOrder[i]] = v; var c = from b in this.Components.Values where b is Input && b.Outputs.ContainsKey(inputsOrder[i]) select b; if (c.Count() > 0) c.First().Outputs[inputsOrder[i]] = v; } return true; } /// /// vypise vystupy site ve spravnem poradi /// /// public string OutputsToString() { string line = ""; for (int i = 0; i < outputsOrder.Count; i++) { var c = from b in this.Components.Values where b is Output && b.Inputs.ContainsKey(outputsOrder[i]) select b; if (c.Count() > 0) { bool v = c.First().Inputs[outputsOrder[i]]; //bool v = this.Outputs[outputsOrder[i]]; if (v) line += "1"; else line += "0"; } } return line; } public override bool Evaluate() { foreach (var cmp in this.Components.Values) { cmp.InputsSet = 0; } Queue q = new Queue(this.inputsOrder); while (q.Count > 0) { var i = q.Dequeue(); var c = from b in this.Components.Values where b.Inputs.ContainsKey(i) || b.Inputs.ContainsKey("out+" + i) select b; var o1 = (from b in this.Components.Values where b.Outputs.ContainsKey(i) select b); if (c.Count() == 0 || o1.Count() == 0) continue; var o = o1.First().Outputs[i]; foreach (var a in c) { string inp = i; if (!a.Inputs.ContainsKey(i)) inp = "out+" + i; a.Inputs[inp] = o; a.InputsSet++; if (a.InputsSet == a.Inputs.Count) { if (!(a is Net)) { if (a.Evaluate()) { foreach (var output in a.Outputs.Keys) { q.Enqueue(output); } } else return false; } } } } return true; } public override Drawing Draw() { throw new NotImplementedException(); } public override bool LoadFromXML(XElement elem) { this.Components.Add("net", this); foreach (var e in elem.Elements()) { string n = e.Name.LocalName.ToLower(); if (n == "input") { XAttribute idE = e.Attribute(XName.Get("id")); if (idE == null) return false; string id = idE.Value.ToLower(); if (this.Components.ContainsKey(id)) return false; this.inputsOrder.Add(id); if (!this.Inputs.ContainsKey(id)) this.Inputs.Add(id, false); Input i = new Input(); if (!i.LoadFromXML(e)) return false; this.Components.Add(id, i); if (!this.AllOutputs.Contains(id)) this.AllOutputs.Add(id); if (!i.Outputs.ContainsKey(id)) i.Outputs.Add(id, false); } else if (n == "output") { XAttribute idE = e.Attribute(XName.Get("id")); if (idE == null) return false; string id = "out+" + idE.Value.ToLower(); if (this.Components.ContainsKey(id)) return false; this.outputsOrder.Add(id); if (!this.Outputs.ContainsKey(id)) this.Outputs.Add(id, false); Output o = new Output(); if (!o.LoadFromXML(e)) return false; this.Components.Add(id, o); //this.AllInputs.Add(id); if (!o.Inputs.ContainsKey(id)) o.Inputs.Add(id, false); } else if (n == "gate") { XAttribute atr = e.Attribute(XName.Get("type")); if (atr == null) return false; string type = atr.Value.ToLower(); if (type == "and" || type == "or" || type == "not" || type == "xor") { Gate g = new Gate(this); if (!g.LoadFromXML(e)) return false; string id = g.Outputs.Keys.First(); if (this.Components.ContainsKey(id)) return false; this.Components.Add(id, g); } else { try { XDocument doc = XDocument.Load(type); var ele = (from c in doc.Descendants() where c.NodeType == System.Xml.XmlNodeType.Element && c.Name.LocalName.ToLower() == "net" select c).First(); Net net = new Net(); if (!net.LoadFromXML(ele)) return false; if (this.Components.ContainsKey(type)) return false; this.Components.Add(type, net); } catch (Exception) { MessageBox.Show("Nepodařilo se otevřít soubor.", "Chyba", MessageBoxButton.OK, MessageBoxImage.Error); return false; } } } else { return false; } } return true; } public override XElement SaveToXML() { throw new NotImplementedException(); } } public enum GateType { And, Or, Xor, Not } public class Gate : BaseComponent { public Gate(Net baseNet) : base() { BaseNet = baseNet; } GateType Type { get; set; } public override bool Evaluate() { var b = false; switch (Type) { case GateType.And: b = true; foreach (var i in this.Inputs.Values) { b = b && i; } break; case GateType.Or: foreach (var i in this.Inputs.Values) { b = b || i; } break; case GateType.Xor: int trues = 0; foreach (var i in this.Inputs.Values) { if (i) trues++; } if (trues % 2 == 1) b = true; break; case GateType.Not: b = !this.Inputs.Values.First(); break; default: break; } this.Outputs[this.Outputs.Keys.First()] = b; return true; } public override Drawing Draw() { throw new NotImplementedException(); } public override bool LoadFromXML(XElement elem) { XAttribute atr = elem.Attribute(XName.Get("type")); if (atr == null) return false; string type = atr.Value.ToLower(); if (type == "and") Type = GateType.And; else if (type == "or") Type = GateType.Or; else if (type == "xor") Type = GateType.Xor; else if (type == "not") Type = GateType.Not; else return false; foreach (var e in elem.Descendants()) { string n = e.Name.LocalName.ToLower(); if (n == "input") { if (this.Inputs.Count > 0 && Type == GateType.Not) return false; XAttribute idE = e.Attribute(XName.Get("id")); if (idE == null) return false; string id = idE.Value.ToLower(); //if (this.BaseNet.AllInputs.Contains(id)) return false; //this.BaseNet.AllInputs.Add(id); if (!this.Inputs.ContainsKey(id)) this.Inputs.Add(id, false); } else if (n == "output") { if (this.Outputs.Count > 0) return false; XAttribute idE = e.Attribute(XName.Get("id")); if (idE == null) return false; string id = idE.Value.ToLower(); if (this.BaseNet.AllOutputs.Contains(id)) return false; this.BaseNet.AllOutputs.Add(id); if (!this.Outputs.ContainsKey(id)) this.Outputs.Add(id, false); } else return false; } return this.LoadBounds(elem) && this.Inputs.Count > 0 && this.Outputs.Count == 1; } public override XElement SaveToXML() { throw new NotImplementedException(); } } public class Input : BaseComponent { public override bool Evaluate() { return true; } public override Drawing Draw() { throw new NotImplementedException(); } public override bool LoadFromXML(XElement elem) { return this.LoadBounds(elem); } public override XElement SaveToXML() { throw new NotImplementedException(); } } public class Output : BaseComponent { public override bool Evaluate() { return true; } public override Drawing Draw() { throw new NotImplementedException(); } public override bool LoadFromXML(XElement elem) { return this.LoadBounds(elem); } public override XElement SaveToXML() { throw new NotImplementedException(); } } }