So equations are quite simple;
You have a number, an operator, and another number.
Simple… Until you try and pass in the variable from another script and try to follow BEDMAS or PEMDAS or whatever else you want to call the order of operations.
So I did a thing for a group prototype to try and handle it, using floats and strings
You can start off with a simple method
float answer; void EquationSolver (float _numOne, float _numTwo, string _op) { }
The first issue: passing an operator.
I searched for ages trying to find something but couldn’t find anything.. So I found the solution was to use a string and do stuff from there.
So here’s how it would basically look :
float answer; void EquationSolver (float _numOne, float _numTwo, string _op) { // goes through all the operators one by one if (_op == "/") answer = _numOne / _numTwo; else if (_op == "*") answer = _numOne * _numTwo; else if (_op == "+") answer = _numOne + _numTwo; else if (_op == "-") answer = _numOne - _numTwo; }
This works really well if you have an equation for only 2 numbers and an operator. But the you may as well just have it in one line anyway!
float answer = _numOne * _numTwo;
So what if you had a list of numbers, and a list of operators like us then? Well I started with the same basic idea as before, but using a list of the gameObjects we added, instead of separate floats.
using System.Collections.Generic; float answer; void EquationSolver (List <GameObject> _list) { // goes through the list until it finds a new operator // when it finds one, it goes one gameObject before, and one after in the list for (int i = 0; i < i < _ops.Count - 1; i++) { if (_list [i].GetComponent <Operator> ().GetOperator == "/") answer += _list [i-1] / _list [i+1]; else if (_list [i].GetComponent <Operator> ().GetOperator == "*") answer += _list [i-1] * _list [i+1]; else if (_list [i].GetComponent <Operator> ().GetOperator == "+") answer += _list [i-1] + _list [i+1]; else if (_list [i].GetComponent <Operator> ().GetOperator == "-") answer += _list [i-1] - _list [i+1]; } }
Now this had two problems (apart from being difficult to read).
1) It would still ignore BEDMAS and do them in the order in which they were added.
2) It would ignore the fact that some of the numbers had been used already, and used their unchaged state, giving an incorrect answer
Looking pretty bleak atm.. But fear not, I came up with a solution!.. Not overly pretty, but effective. Enter my new found joy in Dictionary’s! The coding one, not the word one.
The concept of a Dictionary (if you’ve never used one before) is basically a more advanced list. Instead of having a zero index for holding values, you have a key which can be an int, a float, or a string (possibly others, but I’m not sure).
I also used a localized string array for the operators so it would always perform the equation in the proper order of operations.
So here’s what I did for the final outcome, making it a public int so it could be called from anything and give back a direct answer:
using System.Collections.Generic; float answer; Dicitonary <int, float> previousCalculation; string [] operators = new string [] {"/", "*", "+", "-"}; public int FinalAnswer (List <GameObject> _list) { // creates a new dictionary and sets the answer to 0 at the start of the equation // this makes sure that it doesn't have anything left from previous equations calculated = new Dictionary <int, int> (); answer = 0; // starts a for loop for each of the operators in the operator list foreach (string _op in operators) { // I could have use a foreach loop again, but this way allows us to select one before and one after for (int i = 0; i < _list.Count - 1; i++) { // checks the gameObjects for the operator we're currently looking for if (_list[i].GetComponent <Operator> ().GetOperator () == _op) { // we create some temporary floats that will be used in the next part of the calculation float a = 0; float b = 0; // checks if the number has already been used // if it has use the calculated number instead of the original one if (calculated.ContainsKey (i-1)) a = calculated [i-1]; else a = _list [i-1].GetComponent <Number> ().GetValue (); // does the same as above, but for the second number if (calculated.ContainsKey (i+1)) b = calculated [i+1]; else b = _list [i+1].GetComponent <Number> ().GetValue (); // performs the various operations based on which operator we are checking if (op == "/") answer = a/b; else if (op == "*") answer = a*b; else if (op == "+") answer = a+b; else if (op == "-") answer = a-b; // will replace the calculated value, or add a new one if there is not one if (!calculated.ConatinsKey (i+1)) calculated.Add (i+1, answer); else calculated[i+1] = answer; // will do the same as above but place it backwards not forwards in the list if (!calculated.ConatinsKey (i-1)) calculated.Add (i-1, answer); else calculated[i-1] = answer; } } } return answer; }
And there you have it! A working equation solver that follows BEDMAS and is dynamic in which operators or numbers you pass through.
Not altogether pretty, but it works!
Feel free to use it or adapt it if you want. But I can’t imagine to many circumstances where this would even be used haha.
EDIT: you can now download a prototype build of ADD for free
1 Pingback