max("abc".indexOf('c'), ("a" + "b").length()) can attack Earth!
I also added a weighting system to the random expression generator to make it easy to progressively generate more complex expressions as the player advances in the game. Initially, only the arithmetic operators and simple integers will be generated. After the player proves herself, we’ll throw in some equality operators. Then some numeric functions. Then some relational operators. Then some logical operators. Then some string methods. And so on.
One big risk that looms over me is how to avoid or handle expressions that exceed the screen dimensions. The way Unity works, I can’t determine the size of the text until the frame after which it first appears. I could resort to just using sprites for every letter, but this would add immense pain to style and size tweaks.
Remaining on my near-term TODO list is handling divide by 0, incorporating variables, and generating parameters appropriate to their context (for example, charAt should usually accept an index that’s in range).
Now, how would you pick off the expression a + b - c / d? Answer this question before reading on.
When I wrote the code to determine the highest-precedent operation in an expression tree, I gave that title to the leftmost-leafmost operation. A two-operand operation gives highest precedence to an operation in its left operand. If the left operand has no operation, then the right operand is given a chance. If it too contains no operation, then the operation itself has the highest precedence:
class BinaryOperation ... def highest_precedent winner = left.highest_precedent if winner.nil? winner = right.highest_precedent if winner.nil? winner = self end end return winner end end
This criteria for precedence seemed a bit too simple when I wrote it—but I shrugged off the doubt. Then a + b - c / d attacked Earth, and I stepped up to defend it. The middle schooler within me shot at the / first, as it has highest precedence. But the leftmost-leafmost operation is +, and that’s what Rator Vaders wanted me to shoot. I realized that my leftmost-leafmost criteria was naive. It is not the same as the precedence rules that we learned in school.
However, the evaluation order is not important here. Whichever of + or / happens first, the outcome is the same, as the two subtrees do not depend on each other:

I wondered, then, what happens in a real programming language? Will a compiler force the division to happen first? I tried to answer that question without resorting to assembly code or Stack Overflow (because that would be cheating). C++’s operator overloading allowed me to hook into the operations:
#include <iostream> class Int { public: Int(int i) : i(i) { } Int operator+(const Int &that) { std::cout << "+" << std::endl; return Int(i + that.i); } Int operator-(const Int &that) { std::cout << "-" << std::endl; return Int(i - that.i); } Int operator/(const Int &that) { std::cout << "/" << std::endl; return Int(i / that.i); } private: int i; }; int main() { Int a(1); Int b(2); Int c(3); Int d(4); Int answer = a + b - c / d; return 0; }
The output vindicated my leftmost-leafmost criteria:
+ / -
At the back of my mind, I was thinking about the expression a + b - c / d as an implementer of a programming language would think of it: as a tree structure that can be evaluated with a post-order traversal. Such a traversal will always evaluate the leftmost-leafmost operation first.
Once you have a tree structure of an expression, you don’t really care about precedence anymore. Precedence was used to construct the tree in the first place, but it’s not important when it comes time to evaluate the tree. The C# specification even states that the evaluation order is left to right. Apparently the C++ specification leaves execution order open to the compiler writer.
So, this has been a big day of for me. I learned that execution order and precedence are different notions. Now I must gracefully inflict that knowledge on my Rator Vaders players, who are closer to grade school than implementing a programming language.
]]>But this week I got back on track. I incorporated real expressions, an Apple II font, some animations when subexpressions get resolved, random expression generation, background music and sound effects, and user input!
Next on my TODO list is incorporating function calls and variable assignments and references.
]]>%. I’ve wanted to use this in my introductory programming courses, but alas, my TODO list is more of a TODO stack. The oldest items get the least attention. So, I performed a simple trick. I pushed onto my TODO stack a working group at ITiCSE 2016 for making games to teach computer science. This new item has my attention, and this game will get made.
The game is called Rator Vaders. It’s like Space Invaders, but the only aliens here are expressions. As they fall from the sky, you must defend Earth by picking off the highest precedent operator/method and evaluating it. A correct answer replaces the subexpression. The process repeats until you are left with a literal value, which may be reduced to ashes with a shot from your ALU blaster.
To help document my progression, I’m going to capture weekly snapshots of its development. Let’s commit to each Friday throughout the summer. Sound good? Here’s the first snapshot:
In this first week, we have blocked out a player who can move left and right. Standing in for an expression we have a few blocks. The middle one is the highest precedent operation, and the two on the side have lower precedence. Shooting the middle causes a new expression to start falling from the sky. It’s crude, but it’s my starting point after a couple of hours work.
]]>