Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Data;
- using System.Drawing;
- using System.Linq;
- using System.Text;
- using System.Net;
- using System.Text.RegularExpressions;
- using System.Threading.Tasks;
- using System.Windows.Forms;
- using System.IO;
- using System.Collections.Specialized;
- using System.Net.NetworkInformation;
- namespace WindowsFormsApplication1
- {
- public partial class Form1 : Form
- {
- public bool CheckForInternetConnection()
- {
- try
- {
- Ping myPing = new Ping();
- string host = "8.8.8.8";
- byte[] buffer = new byte[32];
- int timeout = 1000;
- PingOptions pingOptions = new PingOptions();
- PingReply reply = myPing.Send(host, timeout, buffer, pingOptions);
- return (reply.Status == IPStatus.Success);
- }
- catch (Exception)
- {
- return false;
- }
- }
- public Form1()
- {
- InitializeComponent();
- label6.Text = "";
- if (!CheckForInternetConnection())
- {
- checkBox1.Enabled = false;
- label5.Text = "Check internet connection";
- }
- else
- {
- checkBox1.Enabled = true;
- label5.Text = "Internet connection is stable";
- }
- label7.Text = "";
- label8.Text = "";
- label9.Text = "";
- }
- bool isErrorGlobal;
- Point pointA = new Point(33, 271);
- Point pointB = new Point(372, 271);
- //Variables
- public List<string> acids = new List<string> //Acids list
- {
- "HNO2", "HNO3", "H2CO3", "HCl", "H3PO4", "H2SiO3", "H2SO2", "H2SO3", "H2SO4", "HClO3","HClO4", "HBr", "HMnO4"
- };
- public Dictionary<string, int> salts = new Dictionary<string, int> //Salts list
- {
- {"NO2", -1}, {"NO3", -1}, {"CO3", -2}, {"Cl", -1}, {"PO4", -3}, {"SiO3", -2}, {"SO2", -2}, {"SO3", -2}, {"SO4", -2}, {"OH", -1}, {"ClO3", -1}, {"ClO4", -1 }, {"Br", -1}, {"MnO4", -1}
- };
- public List<string> saltString = new List<string>() //Salt string list (for checking)
- {
- "NO2", "NO3", "CO3", "Cl", "PO4", "SiO3", "SO2", "SO3", "SO4", "OH", "ClO3", "Br", "MnO4", "ClO4"
- };
- public List<string> metals = new List<string> //Metals
- {
- "Li","Be","Na","Mg","Al","K","Ca","Sc","Ti","V" ,"Cr","Mn","Fe","Co","Ni","Cu","Zn","Ga","Rb","Sr","Y" ,"Zr","Nb","Mo","Tc","Ru","Rh","Pd","Ag","Cd","In","Sn","Cs","Ba",
- "La","Hf","Ta","W","Re","Os","Ir","Pt","Au","Hg","Tl","Pb","Bi","Po"
- };
- public Dictionary<string, int> elems = new Dictionary<string, int> //Elements with ions
- {
- {"H", 1},
- { "Li", 1}, {"Be", 2}, {"B", 3}, {"N", -3}, {"O", -2}, {"F", -1},
- {"Na", 1}, {"Mg", 2}, {"Al", 3}, {"Si", 4}, {"P", -3 }, {"Cu", 2 }, {"S", 6}, {"Cl", -1},
- {"K", 1}, {"Ca", 2}, {"Sc", 3}, {"Zn", 2}, {"Ga", 3}, {"Ge", 4}, {"As", -3}, {"Se", -2}, {"Br", -1},
- {"Rb", 1}, {"Sr", 2}, {"Y", 3}, {"Zr", 4}, {"Mo", 6}, {"Tc", 7}, {"Rh", 3}, {"Ag", 1}, {"Cd", 2}, {"In", 3}, {"Te", -2}, {"I", -1},
- {"Cs", 1}, {"Ba", 2}, {"La", 3}, {"Hf", 4}, {"Ta", 5}, {"W", 6}, {"Re", 7}, {"Os", 4}, {"Ir", 4}, {"At", -1},
- {"Fr", 1}, {"Ra", 2}, {"Ac", 3}, {"Ti", 4}, {"V", 5}, {"Cr", 3}, {"Mn", 4}, {"Fe", 3},
- {"Co", 2}, {"Ni", 2}, {"Nb", 5 }, {"Ru", 4}, {"Pd", 2 }, {"Sn", 4},
- {"Sb", 5}, {"Pt", 4 }, {"Au", 3}, {"Hg", 2}, {"Tl", 1}, {"Pb", 2}, {"Bi", 3},
- {"Po", 4}
- };
- public List<string> activeMetals = new List<string>
- {
- "Li", "K", "Ba", "Ca", "Na", "Cs", "Rb"
- };
- private void button1_Click(object sender, EventArgs e)
- {
- textBox4.Text = ""; //Refresh text
- isErrorGlobal = false; //Refresh error
- string reac1 = textBox1.Text; //Reactant1 text
- string reac2 = textBox3.Text; //Reactant2 text
- string reactionType = ""; //Refresh reaction
- int match1 = Regex.Matches(reac1, @"[a-zA-Z]").Count; //Find letter count (error checking)
- int match2 = Regex.Matches(reac2, @"[a-zA-Z]").Count;
- if (match1 == 0 || match2 == 0) //Check error
- {
- isErrorGlobal = true;
- Error();
- return;
- }
- Term react1 = new Term(); //Term1
- react1.components = new List<Component>();
- Term react2 = new Term(); //Term2
- react2.components = new List<Component>();
- SetTerm(ref react1, reac1, true); //Set Term1
- SetTerm(ref react2, reac2, true); //Set Term2
- if (isErrorGlobal) //If found error, dont go through
- {
- return;
- }
- //Reaction types :
- if (react2.IsEmpty)
- {
- reactionType = "Decompression"; //Not implemented, cause its too hard :D
- textBox4.Text = "Decompression";
- textBox2.Text = "Not implemented, it's way too hard :)";
- return;
- }
- else
- {
- //Main reaction types
- if (react1.isSalt && react2.isSalt && react1.hasMetal && react2.hasMetal)
- {
- reactionType = "Double replacement";
- }
- else if ((react1.isSalt && react2.isMetal) || (react1.isMetal && react2.isSalt))
- {
- reactionType = "Replacement";
- }
- else if ((react1.isHC && react2.text.Contains("O") && react2.termCount == 1) || (react2.isHC && react1.text.Contains("O") && react1.termCount == 1))
- {
- reactionType = "Combustion";
- }
- else if (((react1.isMetal && react2.text.Contains("O") && react2.termCount == 1) || (react1.text.Contains("O") && react1.termCount == 1 && react2.isMetal)) && (react1.hasMetal || react2.hasMetal))
- {
- reactionType = "Oxidization";
- }
- else if ((react1.isMetal && react2.isAcid) || (react1.isAcid && react2.isMetal))
- {
- reactionType = "Replacement (Acid)";
- }
- else if ((react1.isOxide && react2.isAcid) || (react1.isAcid && react2.isOxide))
- {
- reactionType = "Double replacement (Acid)";
- }
- else if ((react1.isMetal && react2.text == "CO2") || (react1.text == "CO2" && react2.isMetal))
- {
- reactionType = "Replacement (C)";
- }
- else if ((react1.isOxide && react2.text == "C") || (react1.text == "C" && react2.isOxide))
- {
- reactionType = "Deoxidation (C)";
- }
- else if ((react1.hasMetal && react2.isSaltFormer) || (react1.isSaltFormer && react2.hasMetal) ||
- (react1.components[0].text == "H" && react1.termCount == 1 && react2.components[0].text == "O" && react2.termCount == 1) ||
- (react1.components[0].text == "O" && react1.termCount == 1 && react2.components[0].text == "H" && react2.termCount == 1) ||
- ((react1.isOxide && react2.isWater) || (react1.isWater && react2.isOxide)))
- {
- reactionType = "Synthesis";
- }
- else if ((react1.isActiveMetal && react2.isWater) || (react2.isActiveMetal && react1.isWater))
- {
- reactionType = "Replacement (Active)";
- }
- else if ((react1.isMetal && !react1.isActiveMetal && react2.isWater) || (react1.isWater && react2.isMetal && !react2.isActiveMetal))
- {
- reactionType = "Replacement (W)";
- }
- else if ((react1.isSalt && react2.isAcid) || (react2.isSalt && react1.isAcid))
- {
- reactionType = "Double replacement (Salt and Acid)";
- }
- }
- //Checking ions:
- FindIons(ref react1);
- FindIons(ref react2);
- //Solving
- Solve(reactionType, ref react1, ref react2);
- //Refresh text
- react1.RefreshText();
- react2.RefreshText();
- if (react1.salt == "OH" && react1.text[react1.text.IndexOf('(') - 1] == 'O')
- {
- react1.text = react1.text.Remove(react1.text.IndexOf('(') - 1, 1);
- }
- if (react2.salt == "OH" && react2.text[react2.text.IndexOf('(') - 1] == 'O')
- {
- react2.text = react2.text.Remove(react2.text.IndexOf('(') - 1, 1);
- }
- if (checkBox2.Checked)
- {
- animation(react1.text, react2.text, textBox2.Text);
- }
- //Final : setting textBox and balancing
- string a = react1.text + "+" + react2.text + "=" + textBox2.Text;
- if(checkBox1.Checked)
- {
- if (CheckForInternetConnection())
- {
- WebClient client = new WebClient(); //Start new client
- progressBar1.Value += 10;
- //Set headers
- client.Headers.Add("user-agent", " Mozilla/5.0 (Windows NT 6.1; WOW64; rv:25.0) Gecko/20100101 Firefox/25.0");
- string b = a; //Make new temp string
- progressBar1.Value += 10;
- b = b.Replace("+", "%2B"); //Replace HTML symbols
- b = b.Replace("=", "%3D");
- string URL = "http://www.webqc.org/balance.php?reaction=" + b; //Set URL
- progressBar1.Value += 10;
- string webData = client.DownloadString(URL); //Download string
- progressBar1.Value += 10;
- //Make Answer
- string answer = webData.Substring(webData.IndexOf("Balanced equation") + 12, 700);
- progressBar1.Value += 10;
- answer = answer.Replace(" ", string.Empty);
- progressBar1.Value += 10;
- answer = answer.Substring(answer.IndexOf("<br>") + 4, 500);
- progressBar1.Value += 10;
- answer = answer.Substring(0, answer.IndexOf("</b>"));
- progressBar1.Value += 10;
- answer = answer.Replace("<sub>", "");
- progressBar1.Value += 10;
- answer = answer.Replace("</sub>", "");
- answer = answer.Replace("<spanclass='blue'>", "");
- answer = answer.Replace("</span>", "");
- progressBar1.Value += 10;
- textBox2.Text = answer;
- //Set Label Text
- checkBox1.Enabled = true;
- label5.Text = "Internet connection is stable";
- }
- else
- {
- //Set Label Text
- checkBox1.Checked = false;
- checkBox1.Enabled = false;
- label5.Text = "Check internet connection";
- }
- }
- else if(!checkBox1.Checked || !CheckForInternetConnection())
- {
- //If not ticked : just set a
- textBox2.Text = a;
- }
- //Reaction type
- textBox4.Text = reactionType;
- progressBar1.Value = 0;
- }
- async Task animation(string term1, string term2, string products)
- {
- label7.Show();
- label8.Show();
- label9.Hide();
- label7.Text = term1;
- label8.Text = term2;
- label9.Text = products;
- Point currentA = pointA, currentB = pointB;
- do
- {
- currentA.X += 1;
- currentB.X -= 1;
- label7.Location = currentA;
- label8.Location = currentB;
- await Task.Delay(10);
- } while (label7.Location.X < 180);
- label9.Show();
- label7.Hide();
- label8.Hide();
- }
- void FindIons(ref Term t)
- {
- //Temp variables
- List<Component> cTemp = t.components;
- List<Component> finalTemp = new List<Component>();
- //Loop thru all components
- for (int i = 0; i < cTemp.Count; i++)
- {
- if (cTemp[i].ion == 0) //If cant find ion (Carbon)
- {
- if (t.termCount > 1)
- {
- //New component C
- Component c = new Component();
- Component cNext = new Component();
- c = cTemp[i];
- cNext = cTemp[i + 1];
- if (cNext.ion > 0) //If there is [O] - ion will be positive
- {
- c.ion = -4;
- }
- else //If [H] - negative
- {
- c.ion = 4;
- }
- //Add to components list
- finalTemp.Add(c);
- }
- else
- {
- //New component C
- Component c = new Component();
- c.ion = -4;
- finalTemp.Add(c);
- }
- }
- else
- {
- //Add to components list, ion already found
- finalTemp.Add(cTemp[i]);
- }
- }
- t.components = finalTemp; //If everything is right Term's components is on his place.
- //Find total ion count (Error check)
- if (t.leftSide && t.termCount > 1)
- {
- int totalIon = 0;
- if (t.isSalt || t.isAcid)
- {
- totalIon = t.components[0].ion * t.components[0].SubCoefficent + t.saltMultiplier * t.saltIon;
- }
- else
- {
- for (int i = 0; i < t.termCount; i++)
- {
- totalIon += t.components[i].ion * t.components[i].SubCoefficent;
- }
- }
- if (totalIon != 0) //If its not equal to 0 (Standard)
- {
- if (t.isOxide)
- {
- BalanceOxide(ref t);
- t.RefreshText();
- }
- else
- {
- Balance(ref t);
- t.RefreshText();
- }
- label6.Text = "Ions fixed!";
- }
- }
- }
- void SetTerm(ref Term t, string text, bool isLeft) //Setting term (Hardest one :D)
- {
- //If text is there
- if (text != "")
- {
- //Temp variable
- string newT = text;
- int coef = 0; //Coefficent
- bool isMetal, isAcid, isSalt, hasMetal, isWater, isHC, isSaltFormer, isOxide = false, isActiveMetal; //Booleans
- //Temp variable
- List<Component> lastComp = new List<Component>();
- //Salt multiplier : like (OH)3
- int saltMultiplier = 1;
- //If it contains [(] [)] - remove it and add salt multiplier
- if (newT.Contains("(") && newT.Contains(")"))
- {
- string a = "";
- if (char.IsDigit(newT.Last()))
- {
- a = newT.Substring(newT.IndexOf(')') + 1, 1);
- newT = newT.Remove(newT.IndexOf(')') + 1, 1);
- saltMultiplier = int.Parse(a);
- }
- newT = newT.Remove(newT.IndexOf('('), 1);
- newT = newT.Remove(newT.IndexOf(')'), 1);
- }
- //Get salt string
- string salt = "";
- //Find coefficent
- if (char.IsDigit(newT.First())) //2<-Cu
- {
- string a = newT.Substring(0, 1);
- coef = int.Parse(a);
- newT = newT.Remove(0, 1);
- }
- else
- {
- coef = 1;
- }
- int termCount = 0; //Terms count
- List<int> termLocation = new List<int>(); //Temp variable : term locations
- List<string> termsWithSubscript = new List<string>(); //Temps with subscripts
- for (int i = 0; i < newT.Length; i++) //Loop thru all
- {
- if (char.IsUpper(newT[i])) //Found start of term
- {
- termCount++;
- termLocation.Add(i);
- }
- }
- for (int i = 0; i <= termCount - 1; i++) //Loop thru all for cutting terms
- {
- string tempTerm = "";
- if (i > termCount - 2) //If it's last one
- {
- tempTerm = newT.Substring(termLocation[i], newT.Length - termLocation[i]);
- }
- else //Else
- {
- tempTerm = newT.Substring(termLocation[i], termLocation[i + 1] - termLocation[i]);
- }
- termsWithSubscript.Add(tempTerm);
- }
- if(termCount == 0)
- {
- isErrorGlobal = true;
- Error();
- return;
- }
- //Check isMetal, isAcid, isSalt, isWater, hasMetal, isHydrocarbon
- isMetal = (metals.Contains(newT) && termCount == 1);
- isAcid = (acids.Contains(newT) || (newT.StartsWith("H") && saltString.Any(newT.Contains)));
- hasMetal = (metals.Any(newT.Contains));
- isSalt = (salts.Keys.ToList().Any(newT.Contains) && hasMetal && !isAcid);
- isWater = (newT == "H2O");
- isHC = (newT.Contains("C") && newT.Contains("H") && termCount == 2);
- isSaltFormer = saltString.Contains(newT);
- isActiveMetal = (activeMetals.Contains(newT));
- //Oxide checking
- if (hasMetal && newT.Contains("O") && termCount == 2)
- {
- isOxide = true;
- }
- if (isSalt)
- {
- int indexEndMetal = 0; //Metal ending index
- foreach (string metal in metals) //Loop thru all metals in [Metals list]
- {
- if (newT.Substring(0, 2).Contains(metal))
- {
- if (coef == 1)
- {
- indexEndMetal = metal.Length; //Index end : metal length
- }
- else
- {
- indexEndMetal = metal.Length + 1; //If coef != 1 : +1
- }
- if (indexEndMetal > newT.Length)
- {
- if (char.IsDigit(newT[indexEndMetal])) //If it's digit : add +1
- {
- indexEndMetal += 1;
- }
- }
- }
- }
- salt = newT.Substring(indexEndMetal, newT.Length - indexEndMetal); //Cut salt
- int saltUpperCount = 0; //Salt terms count
- for(int i = 0; i < salt.Length; i++) //Loop thru all
- {
- if(char.IsUpper(salt[i]))
- {
- saltUpperCount++; //Increment
- }
- }
- if(char.IsDigit(salt.Last()) && saltUpperCount == 1) //If it's digit
- {
- salt = salt.Remove(salt.Length - 1, 1); //Remove
- }
- if(char.IsDigit(salt.First()))
- {
- salt = salt.Remove(0, 1);
- }
- }
- else if(isAcid)
- {
- //H2SO4
- //01234
- int indexEndH = 1;
- if(char.IsDigit(newT[indexEndH]))
- {
- indexEndH += 1;
- }
- string a = newT.Substring(indexEndH, newT.Length - indexEndH);
- if(char.IsDigit(a[0]))
- {
- a = a.Substring(1, a.Length - 1);
- }
- salt = a;
- }
- //Cutting substrings
- List<int> saltSubstrings = new List<int>();
- //Salt ion
- int saltIon = 0;
- for (int i = 0; i < termsWithSubscript.Count; i++) //Loop thru all
- {
- //Temp component
- Component comp = new Component();
- int tempCoef = 0;
- string tempComp = termsWithSubscript[i];
- if (char.IsDigit(tempComp.Last())) //If it's digit
- {
- string a = tempComp.Substring(tempComp.Length - 1, 1);
- tempCoef = int.Parse(a);
- tempComp = tempComp.Remove(tempComp.Length - 1, 1);
- }
- else
- {
- tempCoef = 1;
- }
- //Adjusting text and subcoefficent
- comp.text = tempComp;
- comp.SubCoefficent = tempCoef;
- //Carbon is element with -4 and 4 ion
- if (comp.text != "C")
- {
- //Find elements in all elements list, if no - Error.
- try
- {
- comp.ion = elems[comp.text];
- }
- catch (KeyNotFoundException)
- {
- isErrorGlobal = true;
- Error();
- return;
- }
- }
- else
- {
- //0 for finding in FindIons() function
- comp.ion = 0;
- }
- //If it's salt
- if (isSalt)
- {
- if (salt.Contains(comp.text)) //Find if it's salt
- {
- //Is salt part : for synthesis reaction
- comp.isSaltPart = true;
- saltSubstrings.Add(comp.SubCoefficent);
- }
- }
- lastComp.Add(comp);
- }
- //Salt ion
- if (isSalt || isAcid)
- {
- //Finding salt ion
- saltIon = salts[salt];
- }
- //Apply
- t.text = newT;
- t.coefficent = coef;
- t.components = lastComp;
- t.termCount = termCount;
- t.isMetal = isMetal;
- t.isAcid = isAcid;
- t.isSalt = isSalt;
- t.isWater = isWater;
- t.hasMetal = hasMetal;
- t.isHC = isHC;
- t.leftSide = isLeft;
- t.salt = salt;
- t.isOxide = isOxide;
- t.saltIon = saltIon;
- t.saltSubstrings = saltSubstrings;
- t.saltMultiplier = saltMultiplier;
- t.IsEmpty = false;
- t.isActiveMetal = isActiveMetal;
- t.isSaltFormer = isSaltFormer;
- }
- else
- {
- //String is empty, T will be empty.
- t.IsEmpty = true;
- }
- }
- void Solve(string type, ref Term reac1, ref Term reac2)
- {
- //Products
- Term prod1 = new Term();
- prod1.components = new List<Component>(); //Creating new list.
- Term prod2 = new Term();
- prod2.components = new List<Component>();
- if (type == "Replacement") //Type is replacement (salt + metal)
- {
- if (reac1.isSalt)
- {
- //Product1
- string newT = "";
- //Product2
- string newT2 = "";
- //Solving, swapping salts
- newT = reac1.text;
- newT2 = reac2.text;
- string t2Salt = reac1.salt;
- newT = newT.Remove(newT.IndexOf(reac1.salt), reac1.salt.Length);
- newT2 = newT2 + t2Salt;
- //Setting terms
- SetTerm(ref prod1, newT, false);
- SetTerm(ref prod2, newT2, false);
- //Getting component ions
- int allComponentIons = 0;
- foreach (Component c in prod2.components)
- {
- allComponentIons += c.ion * c.SubCoefficent;
- }
- if (allComponentIons != 0)
- {
- //If it's not 0, call Balance() method
- Balance(ref prod2);
- }
- //Refreshing text
- prod1.RefreshText();
- prod2.RefreshText();
- //After everyhing done show text
- textBox2.Text = prod1.text + "+" + prod2.text;
- }
- else if (reac2.isSalt) //The same, but swapped
- {
- //Swapping
- Term swapTerm = new Term();
- swapTerm = reac2;
- reac2 = reac1;
- reac1 = swapTerm;
- //Product1
- string newT = "";
- //Product2
- string newT2 = "";
- //Solving
- newT = reac1.text;
- newT2 = reac2.text;
- string t2Salt = reac1.salt;
- newT = newT.Remove(newT.IndexOf(reac1.salt), reac1.salt.Length);
- newT2 = newT2 + t2Salt;
- SetTerm(ref prod1, newT, false);
- SetTerm(ref prod2, newT2, false);
- int allComponentIons = 0;
- foreach (Component c in prod2.components)
- {
- allComponentIons += c.ion * c.SubCoefficent;
- }
- if (allComponentIons != 0)
- {
- Balance(ref prod2);
- }
- //Refreshing text
- prod1.RefreshText();
- prod2.RefreshText();
- textBox2.Text = prod1.text + "+" + prod2.text;
- }
- }
- else if (type == "Double replacement") //(salt + salt)
- {
- //Prod1
- string newT = "";
- //Prod2
- string newT2 = "";
- //Solving, Swapping salts
- newT = reac1.text;
- newT2 = reac2.text;
- string saltNewT = newT.Substring(newT.IndexOf(reac1.salt), reac1.salt.Length);
- string saltNewT2 = newT2.Substring(newT2.IndexOf(reac2.salt), reac2.salt.Length);
- if(newT.Contains("(") && newT.Contains(")"))
- {
- newT = newT.Remove(newT.IndexOf("("), 1);
- newT = newT.Remove(newT.IndexOf(")"), 1);
- if(char.IsDigit(newT.Last()))
- {
- newT = newT.Remove(newT.Length - 1, 1);
- }
- }
- if (newT2.Contains("(") && newT2.Contains(")"))
- {
- newT2 = newT2.Remove(newT2.IndexOf("("), 1);
- newT2 = newT2.Remove(newT2.IndexOf(")"), 1);
- if (char.IsDigit(newT2.Last()))
- {
- newT2 = newT2.Remove(newT2.Length - 1, 1);
- }
- }
- newT = newT.Remove(newT.IndexOf(reac1.salt), reac1.salt.Length);
- newT2 = newT2.Remove(newT2.IndexOf(reac2.salt), reac2.salt.Length);
- newT += saltNewT2;
- newT2 += saltNewT;
- //Setting terms
- SetTerm(ref prod1, newT, false);
- SetTerm(ref prod2, newT2, false);
- //Balancing
- Balance(ref prod1);
- Balance(ref prod2);
- //Refreshing text
- prod1.RefreshText();
- prod2.RefreshText();
- textBox2.Text = prod1.text + "+" + prod2.text;
- }
- else if (type == "Combustion") // CH + O2
- {
- //Setting new terms
- string newT = "";
- string newt2 = "";
- //Solving
- newT = "CO2";
- newt2 = "H2O";
- //Setting terms
- SetTerm(ref prod1, newT, false);
- SetTerm(ref prod2, newt2, false);
- //Refreshing
- prod1.RefreshText();
- prod2.RefreshText();
- //Showing
- textBox2.Text = prod1.text + "+" + prod2.text;
- }
- else if (type == "Oxidization")
- {
- //Setting new term
- string newT = "";
- //Solving
- string metal = reac1.text;
- newT = metal + "O";
- //Setting term
- SetTerm(ref prod1, newT, false);
- //Balancing (Oxide!)
- BalanceOxide(ref prod1); //The same as Balance but some oriented for oxygen balancing
- //Refreshing text
- prod1.RefreshText();
- //Showing text
- textBox2.Text = prod1.text;
- }
- else if (type == "Synthesis") //Item + Item -> bigger item
- {
- //Setting new term
- string newT = "";
- //Solving
- if ((reac1.isOxide && reac2.isWater) || (reac1.isWater && reac2.isOxide)) //Metal oxide + water -> Metal hydrooxide
- {
- //Solving
- newT = reac1.components[0].text + "OH";
- //Setting term, balancing, refreshing and showing
- SetTerm(ref prod1, newT, false);
- Balance(ref prod1);
- prod1.RefreshText();
- textBox2.Text = prod1.text;
- }
- else if ((reac1.isMetal && reac2.isSaltFormer) || (reac1.isSaltFormer && reac2.isMetal)) //Metal + salt -> metal salt
- {
- //Solving
- newT = reac1.text + reac2.text;
- //Setting term, balancing, refreshing and showing
- SetTerm(ref prod1, newT, false);
- Balance(ref prod1);
- prod1.RefreshText();
- textBox2.Text = prod1.text;
- }
- }
- else if (type == "Decompression") //Decompression is too hard :D
- {
- textBox2.Text = "Working on it, please wait :)";
- }
- else if (type == "Replacement (Acid)")
- {
- //Solving
- string newT = "";
- if (reac1.isMetal)
- {
- newT = reac1.components[0].text;
- newT += reac2.salt;
- }
- else
- {
- newT = reac2.components[0].text;
- newT += reac1.salt;
- }
- //Setting, balancing, refreshing and showing
- SetTerm(ref prod1, newT, false);
- Balance(ref prod1);
- prod1.RefreshText();
- textBox2.Text = prod1.text + "+H2";
- }
- else if(type == "Double replacement (Acid)")
- {
- //Solving
- string newT = "";
- if(reac1.isOxide)
- {
- newT = reac1.components[0].text;
- newT += reac2.salt;
- }
- else
- {
- newT = reac2.components[0].text;
- newT += reac1.salt;
- }
- //Setting, balancing, refreshing and showing
- SetTerm(ref prod1, newT, false);
- Balance(ref prod1);
- prod1.RefreshText();
- textBox2.Text = prod1.text + "+H2O";
- }
- else if(type == "Replacement (C)")
- {
- //Solving
- string newT = "";
- if(reac1.isMetal)
- {
- newT = reac1.components[0].text;
- newT += "O";
- }
- else
- {
- newT = reac2.components[0].text;
- newT += "O";
- }
- //Setting, balancing, refreshing and showing
- SetTerm(ref prod1, newT, false);
- BalanceOxide(ref prod1);
- prod1.RefreshText();
- textBox2.Text = prod1.text + "+C";
- }
- else if(type == "Deoxidation (C)")
- {
- //Solving
- string newT = "";
- if(reac1.isOxide)
- {
- newT = reac1.components[0].text;
- }
- else
- {
- newT = reac2.components[0].text;
- }
- //Setting, balancing, refreshing and showing
- SetTerm(ref prod1, newT, false);
- prod1.RefreshText();
- textBox2.Text = prod1.text + "+CO2";
- }
- else if(type == "Replacement (Active)")
- {
- //Solving
- string newT = "";
- if(reac1.isActiveMetal)
- {
- newT = reac1.components[0].text;
- newT += "OH";
- }
- else
- {
- newT = reac2.components[0].text;
- newT += "OH";
- }
- //Setting, balancing, refreshing and showing
- SetTerm(ref prod1, newT, false);
- Balance(ref prod1);
- prod1.RefreshText();
- textBox2.Text = prod1.text + "+H2";
- }
- else if(type == "Replacement (W)")
- {
- //Solving
- string newT = "";
- if(reac1.isMetal)
- {
- newT = reac1.components[0].text;
- newT += "O";
- }
- else
- {
- newT = reac2.components[0].text;
- newT += "O";
- }
- //Setting, balancing, refreshing and showing
- SetTerm(ref prod1, newT, false);
- BalanceOxide(ref prod1);
- prod1.RefreshText();
- textBox2.Text = prod1.text + "+H2";
- }
- else if(type == "Double replacement (Salt and Acid)")
- {
- //Solving
- string newT = "";
- string newT2 = "";
- if(reac1.isSalt)
- {
- newT = reac1.components[0].text;
- newT += reac2.salt;
- newT2 = "H";
- newT2 += reac1.salt;
- if(newT2 == "HOH")
- {
- newT2 = "H2O";
- }
- }
- else
- {
- newT = reac2.components[0].text;
- newT += reac1.salt;
- newT2 = "H";
- newT2 += reac2.salt;
- if (newT2 == "HOH")
- {
- newT2 = "H2O";
- }
- }
- //Setting, balancing, refreshing and showing
- SetTerm(ref prod1, newT, false);
- SetTerm(ref prod2, newT2, false);
- Balance(ref prod1);
- if (prod2.text == "H2O")
- {
- BalanceOxide(ref prod2);
- }
- else
- {
- Balance(ref prod2);
- }
- prod1.RefreshText();
- prod2.RefreshText();
- textBox2.Text = prod1.text + "+" + prod2.text;
- }
- }
- //Oxide balancing
- void BalanceOxide(ref Term t)
- {
- int oxideIon = -2; // [O] ion
- int ionOther = t.components[0].ion; //Other metal ion
- int subCoefOxide = 1, subCoefMetal = 1; //Subcoefficents
- for (int i = 1; i < 16; i++) //Looping thru 2
- {
- for (int j = 1; j < 16; j++) //2
- {
- if ((i * ionOther) + (j * oxideIon) == 0) //Bruteforce method for calculating subcoefficent
- {
- //Setting and breaking
- subCoefMetal = i;
- subCoefOxide = j;
- break;
- }
- }
- }
- if (subCoefMetal != 1 && subCoefOxide != 1) //If there is an GCF
- {
- if (subCoefMetal > subCoefOxide)
- {
- for (int i = subCoefMetal; i > 0; i--) //GCF finding algorythm
- {
- if (subCoefMetal % i == 0 && subCoefOxide % i == 0)
- {
- //Fractioning
- subCoefMetal /= i;
- subCoefOxide /= i;
- break;
- }
- }
- }
- else if (subCoefOxide > subCoefMetal) //The same but reversed
- {
- for (int i = subCoefOxide; i > 0; i--)
- {
- if (subCoefMetal % i == 0 && subCoefOxide % i == 0)
- {
- subCoefMetal /= i;
- subCoefOxide /= i;
- break;
- }
- }
- }
- //If they re the same set them as 1, 1
- else if (subCoefMetal == subCoefOxide)
- {
- subCoefMetal = 1;
- subCoefOxide = 1;
- }
- }
- //Setting everything
- Component c1 = t.components[0];
- Component c2 = t.components[1];
- c1.SubCoefficent = subCoefMetal;
- c2.SubCoefficent = subCoefOxide;
- t.components[0] = c1;
- t.components[1] = c2;
- }
- //Balancing (now it's the hardest balancing :D)
- void Balance(ref Term t)
- {
- //Temp variables
- List<Component> newComponents = new List<Component>();
- Term newT = t;
- //Total ion
- int compTotalIon = 0;
- //Is Error
- bool isError = false;
- //A,B,C - subcoefficents
- int a = 0, b = 0, c = 0;
- //Salts ions
- int saltA = 0, saltB = 0;
- if (newT.termCount == 2)
- {
- //If term count is 2
- //Setting newT
- Component a1 = newT.components[0];
- Component b1 = newT.components[1];
- a1.SubCoefficent = 1;
- b1.SubCoefficent = 1;
- if (b1.isSaltPart)
- {
- b1.SubCoefficent = t.saltSubstrings[0];
- }
- saltA = 1;
- newT.components[0] = a1;
- newT.components[1] = b1;
- }
- else if (newT.termCount == 3)
- {
- //If term count is 3
- //Do the same but 1 more
- Component a2 = newT.components[0];
- Component b2 = newT.components[1];
- Component c2 = newT.components[2];
- a2.SubCoefficent = 1;
- b2.SubCoefficent = 1;
- c2.SubCoefficent = 1;
- if (b2.isSaltPart)
- {
- b2.SubCoefficent = t.saltSubstrings[0];
- }
- if (c2.isSaltPart)
- {
- c2.SubCoefficent = t.saltSubstrings[1];
- }
- saltA = b2.SubCoefficent;
- saltB = c2.SubCoefficent;
- newT.components[0] = a2;
- newT.components[1] = b2;
- newT.components[2] = c2;
- }
- //Finding total ion count
- compTotalIon = newT.components[0].ion * 1 + newT.saltIon;
- //If it's not 0
- if (compTotalIon != 0)
- {
- for (int i = 1; i < 16; i++) //Loop thru
- {
- for (int j = 1; j < 16; j++) //2
- {
- if (newT.termCount == 2) //Term count = 2
- {
- //Finding error
- if ((newT.components[0].ion > 0 && newT.saltIon > 0) || (newT.saltIon < 0 && newT.components[0].ion < 0))
- {
- //ERROR
- isErrorGlobal = true;
- break;
- }
- if ((i * newT.components[0].ion) + (j * newT.saltIon) == 0) //Bruteforce
- {
- //Assigning
- a = i;
- b = j * saltA;
- }
- }
- else if (newT.termCount == 3) //If terms = 3
- {
- //Check for error
- if ((newT.components[0].ion > 0 && newT.saltIon > 0) || (newT.components[0].ion < 0 && newT.saltIon < 0))
- {
- //ERROR
- isError = true;
- break;
- }
- //Bruteforce
- if ((i * newT.components[0].ion) + (j * newT.saltIon) == 0)
- {
- //Assigning
- a = i;
- b = saltA * j;
- c = saltB * j;
- }
- }
- }
- }
- }
- else //Else not do 1, saltA, saltB, like CuSO4
- {
- a = 1;
- b = saltA;
- c = saltB;
- }
- //If is error, return
- if (isError)
- {
- isError = true;
- Error();
- return;
- }
- //Finding GCF
- if (newT.termCount == 2)
- {
- //GCF Finding algorythm
- int highest = 0;
- if(a > b)
- {
- highest = a;
- }
- else
- {
- highest = b;
- }
- if(a != 1 && b != 1)
- {
- for(int i = highest; i > 1; i--)
- {
- if(a % i == 0 && b % i == 0)
- {
- a /= i;
- b /= i;
- break;
- }
- }
- }
- //Assigning
- Component a1 = newT.components[0];
- Component b1 = newT.components[1];
- a1.SubCoefficent = a;
- b1.SubCoefficent = b;
- newComponents.Add(a1);
- newComponents.Add(b1);
- }
- //If term count == 3
- else if (newT.termCount == 3)
- {
- //GCF algorythm for 3 numbers
- int[] abc = new int[3] { a, b, c };
- int highest = abc.Max();
- if(abc[0] != 1 && abc[1] != 1 && abc[2] != 1)
- {
- for(int i = highest; i > 1; i--)
- {
- if(a % i == 0 && b % i == 0 && c % i == 0)
- {
- a /= i;
- b /= i;
- c /= i;
- break;
- }
- }
- }
- //Assigning
- Component a2 = newT.components[0];
- Component b2 = newT.components[1];
- Component c2 = newT.components[2];
- a2.SubCoefficent = a;
- b2.SubCoefficent = b;
- c2.SubCoefficent = c;
- newComponents.Add(a2);
- newComponents.Add(b2);
- newComponents.Add(c2);
- }
- //Refreshing and setting to main Term
- t.components = newComponents;
- t.RefreshText();
- }
- void Error()
- {
- //Show error
- textBox2.Text = "ERROR! Write a real elements or check ions!";
- }
- struct Component
- {
- public int ion; //Ion (-2, 2)
- public string text; //Text (Cu)
- public int SubCoefficent; //Coefficent (Cu2 - 2)
- public bool isSaltPart; //True or false (SO4 - part is S or O)
- }
- struct Term
- {
- public string text; //CuSO4
- public int coefficent; //Coefficent before term
- public List<Component> components; //Its components (upper)
- public int termCount; //Term count
- public string salt; //Salt string
- public int saltIon; //Salt ion
- public List<int> saltSubstrings; //Salt subcoefficents
- public int saltMultiplier; //Salt multiplier
- //Booleans
- public bool isMetal;
- public bool isAcid;
- public bool isSalt;
- public bool isWater;
- public bool hasMetal;
- public bool isHC;
- public bool isOxide;
- public bool leftSide;
- public bool IsEmpty;
- public bool isSaltFormer;
- public bool isActiveMetal;
- //Check for errors
- void CheckErrors()
- {
- if(components.Count == 1)
- {
- Component comp = components[0];
- comp.SubCoefficent = 1;
- components[0] = comp;
- }
- }
- //Refresh text
- public void RefreshText()
- {
- RecalculateSaltCoefficent();
- CheckErrors();
- text = "";
- if (!isAcid)
- {
- foreach (Component c in components)
- {
- if (c.SubCoefficent != 1)
- {
- text += c.text + c.SubCoefficent.ToString();
- }
- else
- {
- text += c.text;
- }
- }
- }
- else
- {
- if (components[0].SubCoefficent != 1)
- {
- text = components[0].text + components[0].SubCoefficent + salt;
- }
- else
- {
- text = components[0].text + salt;
- }
- }
- if(isSalt)
- {
- if(saltSubstrings.Count == 2 && saltMultiplier != 1)
- {
- int saltStart = 0, saltEnd = 0;
- string saltNewString = "";
- if(components[1].SubCoefficent != 1)
- {
- saltNewString += components[1].text + components[1].SubCoefficent;
- }
- else
- {
- saltNewString += components[1].text;
- }
- if(components[2].SubCoefficent != 1)
- {
- saltNewString += components[2].text + components[2].SubCoefficent;
- }
- else
- {
- saltNewString = components[2].text;
- }
- saltStart = text.IndexOf(saltNewString);
- saltEnd = saltStart + saltNewString.Length;
- text = text.Remove(saltStart, saltEnd - saltStart);
- text += "(" + salt + ")" + saltMultiplier;
- }
- }
- }
- //Recalculate coefficent
- void RecalculateSaltCoefficent()
- {
- if (isSalt)
- {
- if (saltSubstrings.Count == 2)
- {
- if (components[1].SubCoefficent > saltSubstrings[0] && components[2].SubCoefficent > saltSubstrings[1])
- {
- int newSaltCoefficent = 1;
- newSaltCoefficent = components[1].SubCoefficent / saltSubstrings[0];
- saltMultiplier = newSaltCoefficent;
- }
- }
- }
- }
- }
- //Copy button
- private void button3_Click(object sender, EventArgs e)
- {
- if (textBox2.Text != "")
- {
- System.Windows.Forms.Clipboard.SetText(textBox2.Text);
- }
- }
- //Back button
- private void button2_Click(object sender, EventArgs e)
- {
- Form2 f2 = new Form2();
- f2.Show();
- this.Close();
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement