using System;
using System.Collections;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Xml.Serialization;
using System.IO;
namespace HradlovaSit
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
static funkcni_sit Net = new funkcni_sit(); // Aktivni struktura, ktera se uvnitr rekurzivne pocita
static net sit; // Pasivni data, pouze nactene XML
private void button1_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
textBox1.Text = openFileDialog1.FileName;
}
}
private void button2_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
textBox2.Text = openFileDialog1.FileName;
}
}
private void button3_Click(object sender, EventArgs e)
{
try
{
listBox1.Items.Clear();
XmlSerializer xs = new XmlSerializer(typeof(net));
FileStream f = new FileStream(textBox1.Text, FileMode.Open);
sit = (net)xs.Deserialize(f);
foreach (gate hradlo in sit.gate)
{
Net.hradla.Add(new hradlo(hradlo));
}
foreach (input item in sit.input) // Presuneme pasivni strukturu do aktivni
{
Net.iports.Add(new ioport(item));
}
foreach (output item in sit.output)
{
Net.oports.Add(new ioport(item));
}
sit = null; // Tyto pasivni data jiz nepotrebujeme
StreamReader r = new StreamReader(textBox2.Text);
string inputfile = r.ReadToEnd();
foreach (string line in inputfile.Split(Environment.NewLine.ToCharArray())) // Radku po radce vyplnime vstupy...
{
if (line.Length == Net.iports.Count)
{
int lineid = listBox1.Items.Add("");
int i = 0;
foreach (ioport inputport in Net.iports)
{
inputport.hodnota = (line[i++] == '1');
}
foreach (hradlo hr in Net.hradla)
{
hr.Clear();
}
foreach (ioport oport in Net.oports)
{
foreach (hradlo hr in Net.hradla)
{
if (hr.outputid == oport.id)
{
try
{
oport.hodnota = hr.result(); // ... a timto nechame vypocitat strom potrebny k vystupu tohoto portu.
listBox1.Items[lineid] += Convert.ToInt32(oport.hodnota).ToString();
Application.DoEvents(); //Proti domnělému zaseknutí aplikace
}
catch
{
MessageBox.Show("Nelze provést");
}
}
}
}
}
else
{
if (line.Length != 0)
{
throw new Exception("Nevalidní soubor vstupů!");
}
}
}
}
catch (IOException)
{
MessageBox.Show("Soubor popisu sítě neexistuje!");
}
}
///
/// typ:
/// 1 - input
/// 2 - output
/// hodnota:
/// 0 - 0
/// 1 - 1
/// 2 - chyba
///
class ioport // Vstupni nebo vystupni port site - je to jedno, oboji ma stejne vlastnosti
{
public byte typ;
public string id;
public bool hodnota;
public int x, y, w, h;
public ioport(input i)
{
typ = 1;
id = i.id;
x = i.x;
y = i.y;
w = i.w;
h = i.h;
}
public ioport(output i)
{
typ = 2;
id = i.id;
x = i.x;
y = i.y;
w = i.w;
h = i.h;
}
}
///
/// typ:
/// 1 - AND
/// 2 - OR
/// 3 - XOR
/// 4 - NOT
///
class hradlo
{
public byte typ;
public int x, y, w, h;
public string outputid;
public ArrayList input = new ArrayList();
private bool done = false, cached_result;
///
/// Funkce vracejici vysledek, bud podle cache nebo vypoctem
///
///
public bool result()
{
if (done != true) // Počítáme hradlo pouze pokud jsme jej dosud nevypočítali
{
done = true;
cached_result = Process();
}
return cached_result;
}
///
/// Vytvoří aktivní hradlo
///
/// Pasivní základ
public hradlo(gate inp)
{
switch (inp.type.ToLower())
{
case "and":
typ = 1;
break;
case "or":
typ = 2;
break;
case "xor":
typ = 3;
break;
case "not":
typ = 4;
break;
default:
break;
}
x = inp.x;
y = inp.y;
w = inp.w;
h = inp.h;
outputid = inp.outp.id;
foreach (innerinput i in inp.inp)
{
input.Add(i.id);
}
}
///
/// Hlavní funkce, rekurzivně si zajistí spočtení vstupních hradel a pak se spočítá samo
///
///
private bool Process()
{
bool[] vstupy = new bool[input.Count];
int count = 0;
foreach (string inputid in input) // Zde se z adres hradel a vstupních portů stanou hodnoty
{
foreach (ioport item in Net.iports)
{
if (item.id == inputid)
{
vstupy[count++] = item.hodnota; // Port? Jenom precti
}
}
foreach (hradlo hr in Net.hradla)
{
if (hr.outputid == inputid)
{
vstupy[count++] = hr.result(); // Hradlo? Rekurzivni vypocet!
}
}
}
if (count != input.Count)
{
throw new Exception("Unable to process"); // Pokud se stane, ze z nejakeho duvodu nelze zjistit hodnotu hradla
}
bool output = false;
switch (typ)
{
case 4: // NOT - nemusíme brát více vstupů
return !vstupy[0];
case 1:
output = true; // Pouze při AND musíme začít s 1, u ostatních musíme začít s 0
break;
default:
output = false;
break;
}
foreach (bool p in vstupy)
{
bool lastoutput = output;
if (typ == 1)
{
output &= p;
}
else if (typ == 2) // Postupně dle typu provádí operace
{
output |= p;
}
else
{
output ^= p;
}
}
return output;
}
public void Clear()
{
this.done = false; // Kdyz cachujeme, musime take pri zadani novych hodnot hradlu ricim, ze ma nove udaje
}
} // Aktivni hradlo
class funkcni_sit // Zaklad pro aktivni strukturu
{
public ArrayList hradla = new ArrayList();
public ArrayList iports = new ArrayList();
public ArrayList oports = new ArrayList();
}
#region Pasivni struktura
[XmlRoot]
public class net // Zaklad pro pasivni strukturu
{
[XmlElement]
public input[] input;
[XmlElement]
public gate[] gate;
[XmlElement]
public output[] output;
}
[Serializable]
public class input // Vstupni port site
{
[XmlAttribute]
public string id;
[XmlAttribute]
public int x, y, w, h;
}
[Serializable]
public class innerinput // Vstupni port hradla
{
[XmlAttribute]
public string id;
}
[Serializable]
public class gate // Hradlo samotne
{
[XmlAttribute]
public string type;
[XmlAttribute]
public int y, x, w, h;
[XmlElement("input")]
public innerinput[] inp;
[XmlElement("output")]
public inneroutput outp;
}
[Serializable]
public class inneroutput // Vystupni port hradla
{
[XmlAttribute]
public string id;
}
[Serializable]
public class output // A vystupni port site
{
[XmlAttribute]
public string id;
[XmlAttribute]
public int x, y, w, h;
}
#endregion
}
}