Graphing Calculator

Hello. I am trying to create a game that is mostly based on a graphing calculator, where players can enter the equation of a line they wish to generate. Then, that graph is generated on the screen and the player avatar can walk on that graph to go to where they want to go. I think the greatest issue i am facing right now is generating the equation, because the function is entirely entered by the player so that means I must find a way to somehow take the input (function) and execute it at runtime… Is there a way to do that?

I’m not sure how to construct equation code from it, but you’d start with parsing out a a string the user inputs if you use convectional means of taking input
you could ofcourse come up with a custom solution, maybe have equation building blocks (number, function symbol (+,-,*,/), basically calculator buttons) that the user places sequentially, it’ll make it far easier to code.

edit: there’s a game about corporate drones, i can’t recall its name, but it works in a way much like i described, i’ll try and remember the name and post it. maybe someone else knows what i’m talking about.

edit2: Human Resource Machine

Maybe you can use libraries like NCalc: GitHub - MichaelAguilar/NCalc: NCalc is a mathematical expression parser for .NET.

Expression e = new Expression("Round(Pow([Pi], 2) + Pow([Pi2], 2) + [X], 2)");

  e.Parameters["Pi2"] = new Expression("Pi * [Pi]");
  e.Parameters["X"] = 10;

  e.EvaluateParameter += delegate(string name, ParameterArgs args)
    {
      if (name == "Pi")
      args.Result = 3.14;
    };

  Debug.Assert(117.07 == e.Evaluate());

Or Jace: GitHub - pieterderycke/Jace: Jace.NET is a calculation engine for the .NET platform.

Dictionary<string, double> variables = new Dictionary<string, double>();
variables.Add("var1", 2.5);
variables.Add("var2", 3.4);

CalculationEngine engine = new CalculationEngine();
double result = engine.Calculate("var1*var2", variables);
1 Like

Well you can save some time by using my LogicExpressionParser that I wrote for my L-System example. It’s an improved version of my older ExpressionParser that also supports boolean expressions. The old ExpressionParser supported the conversion into a delegate to allow parameter passing. However the performance and garbage generation wasn’t really great. The LogicExpressionParser returns a NumberExpression where you can set parameters yourself. Any identifier that isn’t known beforehand is considered an external variable / parameter.

Here’s an old example application(WebGL) that used the old ExpressionParser. It uses the parsed expression and evaluates it 2000 times per frame. All variables are simply iterated from -1 to 1 if I remember correctly. You can enter your own expression or choose one of the examples. The old parser was able to parse multiply expressions at once and it returned multiple results if there was a comma between them. If a single expression was parsed it used the result as y value and it’s iteration variable as x value for the graph. If there are two results, the first result was used as x, the second one as y coordinate.

Note: the parser is a bit picky. You can not use an unary minus directly. You have to use brackets. So this won’t work:

x * -5 but this does: x * (-5). Note that you can register custom functions and constants. I’ve added most Math methods. Currently I don’t have a Unity installation at hand and I haven’t used this class for ages- Though if you have questions feel free to ask.

How it works

This parser uses a quite naive approach to parse the expression. Since the result is a custom expression tree we just have to think about what the root node would look like. We all know the order of operations. Though the top / root node is actually the last operation you do. That’s why the parser essentially does a bottom up parsing. it first splits the string at + and - signs to create an addition node. Each of the remaining parts are sub expressions. So we go through the order of operations in reverse order so the highest priority is handled last. This approach has one flaw: brackets. Since there could be an addition inside a bracket that should be executed first (and parsed last) we can’t split an infix notation at the + and - signs. The solution was simply to parse out the brackets first and replace each bracket with a placeholder reference before doing the actual parsing. So each cut out bracket will be parsed seperately.

Note that we don’t need a subtraction node or a division node. Instead we only had addition and multiplication as subtraction and division is just the same as addition and multiplication, just with an extra step. So a division requires the reciprocal / inverse of the divisor and a subtraction requires the negative value.

Note that the parser has a “parsing context” which is responsible for providing methods and constants which are shared between multiple parsed expressions. On the other hand each parsed expression has an expression context. It’s reponsible for handling the “variables” that the expression needs. When calling ParseNumber on the parser you can provide a seperate / new ExpressionContext. If you don’t pass one the parser will used a shared expression context for all expressions.

Finally, because someone else had an issue with it in the past, the expression context by default contains common variables / constants. So watch out ^^.

1 Like