Robots-HOWTO Writing programs for GNU Robots Jim Hall _____________________________________________________________________ Introduction _____________________________________________________________________ Hi, and welcome to GNU Robots! I was going to call this file `api.txt' but I figured that wouldn't be very helpful. And I can tell right off the bat that I'm not just going to talk about the GNU Robots programming API. But I will talk about that quite a bit, since it's so important to using GNU Robots. GNU Robots is a game/diversion where you construct a program for a little robot, then set him loose and watch him explore a world on his own. The robot program is written in Scheme, and is implemented using GNU Guile. GNU Robots is an ideal way to introduce someone to the fundamentals of computer programming. Scheme is a very simple language to learn, and by writing Scheme programs for GNU Robots, you can immediately enjoy the results of your work. That said, I'll disclose now that I am not, by nature, a Scheme programmer. I only picked up a bit of Scheme when I created GNU Robots, and I found that the GNU project had created this wonderful extension library that is GNU Guile. In order to use my own program, I had to learn a bit of Scheme. It wasn't hard. Did I mention that Scheme is a simple language to learn? _____________________________________________________________________ Writing programs _____________________________________________________________________ Gosh, what's the best way to introduce computer programming with GNU Robots? I guess I'm not the kind of person who can teach someone else to do computer programming. So I'll take the easy way out: Most of writing programs for GNU Robots involves writing Scheme code. Remember, your robot program is just a Scheme program. So go buy yourself a nice introduction to Scheme book, if you don't already have one. Or, if you're a particularly brave person, see what you can pick up from the robot examples under the `scheme/' directory. Scheme is not a difficult language to pick up, both for programmers and for those new to programming. I would recommend that you adopt a "function" approach to programming a GNU Robot. Many people will refer to this as a "divide and conquer" strategy, and I find it works well. What this means is that you will want to identify the basic kinds of tasks that a robot can perform, then group those into particular kinds of activities. For example, one basic activity for a robot might be to pick up something directly in front of it, then move into the space that is now empty: (define (grab-and-move) (robot-grab) (robot-move 1) ) The `define' statement is from Scheme, and allows us to define a function called `grab-and-move'. The function consists of two statements: `robot-grab' to pick up a thing immediately in front of the robot, and `robot-move' to move the robot a given number of spaces. That was easy. Now, let's try another. The whole goal of GNU Robots is to get the highest score that you can. To increase your score, you need to pick up prizes. So let's create a function that allows our little robot to pick up some prizes. We'll build on the `grab-and-move' function that we defined above. (define (grab-prize) (if (eqv? (robot-feel "prize") #t) (grab-and-move)) ) This is not so scary a statement, if we look at it a piece at a time. The `eqv?' statement compares the truth value of two expressions. In this case, we compare a test expression against a literal true value (`#t'). Our test expression is `(robot-feel "prize")' which will return a `#t' value if the little robot is able to detect a prize in the space immediately in front of it. If the `eqv?' statement is successful (the two expression are the same, or in other words the robot is able to feel a prize in the space right in front of it) then Scheme will execute the `grab-and-move' function. In plain English: if the robot detects a prize in the space immediately before it, the robot will pick it up, and move forward into that space. But every time you make the little robot take an action, you cause it to use energy. To restore its energy levels, it needs to find and consume food. So let's create a function similar to the above that picks up a food item: (define (grab-food) (if (eqv? (robot-feel "food") #t) (grab-and-move)) ) As you can see, the `grab-food' function is virtually identical to the `grab-prize' function. I don't think you need me to explain the difference. From here, you are on your way to creating a cool robot that you can set loose in GNU Robots. It's just a matter of picking up some more of the flow control structures like do-while loops and more of the if-then tests. Then you'll have a fine robot program to play with. _____________________________________________________________________ Robot actions _____________________________________________________________________ But the question you're probably waiting to have answered is: "What can I make the little robot do?" Ah, that's the list of `robot-*' functions. Here is a table of all the GNU Robots functions, called primitives, that you can use in your robot program. Each primitive has an energy cost associated with it. Note that some primitives will take an argument, and some will not. If an argument is a number, I'll print `N' after the function name. If the argument is a GNU Robots "thing" then I'll print `TH' after the function name. If the primitive does not take an argument, I will print nothing. PRIMITIVE ENERGY ACTION ===================================================================== robot-turn N -2 Turns the robot N spaces to the right or left. If `N' is a positive number, the robot turns to the right. If `N' is negative, the robot turns to the left. Every turn has a cost of -2, so if you `robot-turn 2' then the cost is -4 to your energy. --------------------------------------------------------------------- robot-move N -2 Moves the robot N spaces forwards or backwards. If `N' is a positive number, the robot moves forwards. If `N' is negative, the robot moves backwards. Every move has a cost of -2, so if you `robot-move 2' then the cost is -4 to your energy. --------------------------------------------------------------------- robot-smell TH -1 Smells for a thing. If the thing is in the surrounding eight spaces, the function returns a true (`#t') value. --------------------------------------------------------------------- robot-feel TH -1 Feels for a thing in the space directly in front of the robot. If the thing is detected in that space, the function returns a true (`#t') value. Note that you can feel a baddie, and not take any damage. --------------------------------------------------------------------- robot-look TH -1 Looks ahead across empty spaces for a particular thing. If the thing is seen, the function return returns a true (`#t') value. Note that this is sort of a brain-dead function, in that it does not provide the distance to the thing. The robot cannot look behind objects, so if you look for a food item, and there is a prize item in the way, the function returns false. --------------------------------------------------------------------- robot-grab -5 Attempts to pick up what is in the space directly in front of the little robot. Note that you should not try to pick up baddies or walls. If the item is food, you increase your energy by +10. If the item is a prize, you increase your score by +1. The function returns a true (`#t') if the robot was able to pick the thing up. --------------------------------------------------------------------- robot-zap -10 Uses the robot's little gun to zap whatever is in the space directly in front of it. If you were able to zap something (a baddie, or even a prize or food) then the function returns a true (`#t') value. --------------------------------------------------------------------- robot-stop 0 Exits GNU Robots immediately. --------------------------------------------------------------------- robot-get-shields 0 Returns the level of the little robot's shields. --------------------------------------------------------------------- robot-get-energy 0 Returns the level of the little robot's energy. --------------------------------------------------------------------- robot-get-score 0 Returns the robot's score (how many prizes have been picked up.) ===================================================================== And what kinds of "things" are out there to be detected by `robot-smell', `robot-feel' and `robot-look'? Here is a list of all possible things in the GNU Robots world: THING DESCRIPTION ===================================================================== baddie A nasty little critter that is generally bad for your health. Either leave these alone, or zap them. Don't try to pick them up, or you will inflict damage to your shields. Don't bump up against them--that doesn't feel too good, either. --------------------------------------------------------------------- space An empty space. There's nothing interesting here. --------------------------------------------------------------------- food Yum! A health item that will help to restore +10 points of your robot's energy levels. --------------------------------------------------------------------- prize Pick these up! This will add +1 point to your score. Remember, the goal of GNU Robots is to get the highest score! --------------------------------------------------------------------- wall An obstacle. You can't zap these, so you better go around them. Trying to grab a wall does nothing to you, but bumping up against one will inflict damage to your shields. ===================================================================== _____________________________________________________________________ Go try it! _____________________________________________________________________ Okay, that's about all the information you should need to set you on the way to writing really cool GNU Robots programs. Have fun!