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

 

Advertisements