uHerbert(pronounce micro-Herbert, or you-Herbert, or mu-Herbert,..) is an implementation of a game called Herbert, where you have to solve levels by programming a robot. If you fancy programming and solving puzzles, you'll like this game. Otherwise, you might think this is just one of those weird things only meaningful to computer scientists (if ever).
The game consists of a series of levels. Levels contains three kinds of entities
In each level your goal is to write the smallest possible program that makes the robot press all the white buttons in a row (i.e form a complete sequence of white buttons without touching gray ones).
You write the program that your robot will execute in a special language called "h". The h-language supports three fundamental primitives:
For example the program "sssslssssr" means "move four units straight, then turn to your left, move four units straight, then turn right." Of course, any level may be solved just with these. But the real objective is to write small programs (the smallest possbile). In order to do that you'll have to use functions. Functions are just a way to group a sequence of commands that you can reuse many times. For example, here is a program that creates a function:
The first line defines the function. Function have names consisting of one lower case letter (here we named it 'f'), after the function name comes a ':'(colon) then the instructions (called the function body, here it is 'ssss'), and a new line terminates the definition. Now you can "call" the function simply using its name as a new instruction, that is "flfr" is now equivalent to "sssslssssr". Note that you cannot name a function 'r', 's' or 'l' since those three letters are reserved for the three primitives of "h".
Function bodies can contain any instructions even other function calls. For example:
f:ssss q:flfr q
This program is equivalent to the above. Note how it defines two functions ('f' and 'q'), and how the second one calls the first. Functions can even call themselves, this is called recursion:
In this program we define a function that executes an 's', and then calls itself which executes 's', which calls 'f' again .... etc. This means that, when executing the 'f' the robot well keep moving forward indefinitly.
Functions can take arguments to control their behavior. There are two types of arguments: instruction arguments, and numeric arguments. Here is an example of numeric arguments:
The 'f' function takes a single argument (called 'A'). Argument names must be one upper case letter. When using such a function you must append the parameters you want to pass (surrounded by round brackets) to the function name. In the example, we passed 5 as the value of A. The 'f' function will execute "sssl" and then calls itself with a parameter of A-1. That is, calling f(4) will call f(3), which will call f(2), which will call f(1). Calling f(1) will result in the execution of "sssl" but f(0) will never be called. This is because if one of the numeric parameters to a function call is zero or less, the call is not performed at all. In summary calling f(4) will result in "ssslssslssslsssl". You can use any expression (for numeric parameters) involving constants (such as 1, -5,..), argument names (A,B,..), plus sign ('+') and minus sign ('-').
There another kind of arguments called instruction arguments. Here is an example:
Here the parameter passed to 'f' is not supposed to be a number but an instruction sequence (like "ssslssl"). In order to invoke the instuction sequence passed as an argument simply use the argument name as a function call (as in "f(A):sAlA"). In the above example, f is called with a single 'l' instruction as a parameter. 'f' then invokes/executes its parameter, before calling itself with the same parameter to which it appends a new 's'. In the end this will result in the following (infinit) instruction sequence: "llslsslssslsssslssssslssssss..."
Of course, you can have more than one argument and you can mix both types within the same function:
Now f(s,5) will result in "srssrsssrssssrsssssr"
That's it! You know all you need to know to write "h" programs.
Here is a function that advances forward by the amount specified as an argument:
f(5) means "sssss". Now, here is a function that uses 'f' to make the robot draw a square with its trail. The size of square side is given as a argument:
Which you can read "advance A-times, turn left, advance A-times, turn left.."
Anis Benyelloul, at the time of writing (2006), algerian student of 21, finishing his last year at the INI (Institut National d'Informatique) (National Institute of Computing). Has been interested in computers since childhood, and began self-studying when he was 15. He is a GNU/Linux-addict and is very interested in free software. He hates speaking about himself using 'he', and needs to write a better/longer bio :) He can be contacted at email@example.com.