This page will introduce you to Light-Bot, a fun little game that we’ll play during the first day of class. Although it seems simple, Light-Bot foreshadows some interesting aspects of more sophisticated computer programming. (We’ll also use MIT's Scratch system before we move on to the “full-fledged” Java programming language in a week or so.)
We’ll use this page as a guide during class, but you should also feel free to use it for review later on.
The basic idea behind Light-Bot is to move a little robot around a in a grid world; you “win” a game level by having the bot light up special blue squares in the grid. The actual lighting happens when the bot squats on the squares via special command. The robots movements are controlled by a program which you “write” by dragging little command tiles into a scripting area of the interface.
Well, it’s really easier to just show you than it is to explain: let’s try out the first few levels of the game together, in class: in other words, you should also follow along at your computer while we go.
Two basic commands allow the robot to move forward and to light a blue cube by squatting. They’re highlighted in yellow by the game to help you find them. Just click on the tiles in the top row and then place the, where you want in the MAIN METHOD section on the right.
For what it’s worth, the robot cannot move forward if it’s at the edge of the board or in front of a block (try it out on the next level!). Nothing terrible happens: the bot just “spins its wheels” in place.
Two more commands allow the robot to turn left or right, which it will need to do in order to get around taller obstacles in the grid.
It takes a bit of practice to see direction of turn which is which: try putting yourself “in the robot’s head” to predict which way it will turn.
Another command allows you (or rather, the robot!) to jump up on top of a block which is in the way. (Notice how natural it is to start identifying with the robot; this sort of role-playing will be useful even in more complex programming environments later on.)
You also need to use the same jump command if you want to jump down from a height: you (... er, it) can’t get “hurt” from the fall, but you can’t just walk forward off the edge of a cliff, either! (The robot is apparently sturdy enough to jump quite a ways down, but only strong enough to jump up one level at a time).
While some of the later levels of the game are quite challenging, the early ones may seem a bit too easy. One thing you can do to make your robot a little more lively is to add a few extra moves to his (dull) routine, just to spice it up a bit. Rather than just moving forward, for example, you might try having him spin around, or jump up and down.
Here’s what Level 4 looks like:
Try to work out a solution for this level on your own (or work with a partner) during lecture. Be prepared to share your work with the class ... especially if you spice up your solution with some special moves!
This means that you’ll have to write down your work to hand in an assignment (see the worksheet provided in class by your instructor or click here for an on-line, PDF version).
(Check out these cool Light-Bot 2.0 game boards created by Talia, age 9: ♥ ♥ ♥ )
Why is working with the Light-Bot actually “programming”? Partly it’s that you “write” the instructions for the robot when you drag the tiles into the script area; the robot then follows your instructions during a later “run” phase of the game. Programming generally has this overall structure: one writes a program, which is stored, communicated, propagated, disseminated, etc., to other times and places. It can then be run (or performed) over and over again, in different circumstances and for different reasons.
(As opposed to what? Well, in many games, you play in the dynamic part, identifying directly with the “character” itself: you press your thumbs on the little buttons while the character is in play, right in the midst of the action, rather than writing out instructions in advance, in a prior stage.)
In this respect programming is like many other activities that use written language: an author creates an abstract artifact (a written text) which can be used to communicate to various other people in distant times and places. (We are so used to this trick that we forget how magical it would seem to people who had no writing in their culture!)
But programming is even more powerful than this: the written texts are meant to be performed, dynamically, in a rich environment which may include text, graphics, sound, etc. In this sense programming is almost like writing a play for a theatre performance. Programs can also be written to react to circumstances in their environment and even to interact with their audience, just as in some more avante-garde kinds of theatre. But programs can even be written so that when they are later run, they can learn to adapt to new circumstances, dynamically, in different ways for different runs of the same program. In this sense they are much more powerful than traditional written texts, and seem to approach the sophistication of living things.
Of course it becomes more and more difficult to write programs with such complex behaviors, ones
which must respond to unknown or even changing circumstances as they run.
Imagine writing a Light-Bot script that will work in a game level you haven’t even seen
yet, or one where the landscape changes as the robot runs ... or even where the rules of the
game change over time!
Real programming languages and tools offer considerably more flexibility than Light-Bot does,
including the ability to “sense” their environment and take actions which depend
upon perceived conditions...
but we’ll learn more about that as we go through the semester!
To introduce the important idea of functions, let’s take a look at Level 5 and try to solve it together in class:
With this level, note that we have to fill up the entire main script space in order to get the robot to it’s final goal. (At least, that’s the only way I can figure out how to do it!) Hmmmm! We better hope these levels don’t get too much more complicated ... .
For later levels of the game, we will need to use functions: these are the two extra script areas labeled FUNCT. 1 and FUNCT. 2, and located just below the area labelled MAIN METHOD. You can fill up these extra areas of the script with more tile commands, but in order to get to them, you have to use the new tile commands labeled ƒ1 and ƒ2.
Light-bot functions are like the abbreviations or definitions used in natural languages like English: when we have a phrase or idea that we know we will want to use often, but in a shorter form, we come up with a name for it, like USA for “the United States of America” or WU for “Willamette University”. Even words for new ideas are like this: consider that the word spork didn’t really mean anything until a few years ago. We could explain what we mean (“that little utensil that looks like a spoon and a fork combined”) every time we wanted to refer to the thing itself, but it would get pretty tiresome pretty fast. More importantly, there's a kind of extra value that comes from naming things: the corresponding concept becomes an integral part of our mental toolkit once we choose a name for it: to name a thing is to own it, at least conceptually.
In Light-bot, we can define a commonly-used sequence of commands by dragging the corresponding tiles into one of the function areas. We can then use that definition by putting one of the two function command tiles into our main script. When the program runs (i.e., when the robot does his thing), the uses of the function tiles are automatically, dynamically expanded into the sequence of commands in the definition. Furthermore (and this is the important part!), we can do this repeatedly; that is, we can use the function command tile several times in a given script, and get the same expansion each time.
You might visualize the process something like this: we have a sequence of commands, some of which are function calls, expanding into corresponding definitions:
When we actually run the program, when we get to the point of a function call, we hop down to the definition section for that function, do the commands for that definition, then hop back again (the hop back is called a return). Here the dynamic jump for the calls are labeled in green and those for the returns are labeled in red:
Now, there are two main things to remember about functions: one is that they allow us to get extra commands when we need them. That’s important in Light-Bot, where there is a real premium on scripting space. The other thing is that they allow us to capture patterns of action and turn them into new concepts: this sort of conceptual leverage is important in Light-Bot, too, but becomes especially crucial in more complex programming environments.
We can use functions to get some extra room even if we don’t use them to abstract out patterns. For example, you could write your MAIN METHOD so that it just calls ƒ1 at the very end, then continue writing our script in the FUNCT. 1 section, and similarly for ƒ2 at the end of ƒ1. In this way, we can use functions just to stitch longer sequences together.
But if we want to use functions for repetition, how do we come up with a definition? The crucial step is to identify patterns that come up in our intended script. One way to do this is to plan out a script of commands and actually notice a pattern directly by observation. But more often we see the pattern in the “physical” structure of the Light-Bot level we’re working on. In other words, we notice that specific portions of the board look similar to each other, and thus that we can gain an advantage (in terms of fewer tiles used) by putting together a function definition to handle the common parts. When these similarities aren’t so obvious, we can always fall back on the idea of finding a pattern in the actual script; for example, we can write as much of the script as we can in the main method section, then look for the patterns and start to move some of the tiles into a function definition. Or, we can write out a plan on paper (if it won’t fit in the main section) and look for patterns there
In either case, using functions is crucial to getting our little bot to his goal in many of the later levels, and the crucial idea behind functions (called abstraction) is extremely important to real programming later on.
Depending on the amount of time in your lecture and the progress you make as a class, your instructor will assign you to complete one or two levels of the Light-Bot game from among levels 6, 7 and 8.
You may work on these levels alone or in pairs, and you should record your solutions on the worksheet handed out in class (or print a copy from this handy link).
Work on the assignment during your lab time or at home, or come in to lab (when it’s not in use for classes) during the week. In any case, have your completed levels ready for the next class period. (You may want to load them up on the computer from the worksheet so that you can show them to the rest of the class.)
As we saw above, you can use function calls to simulate repeated actions (what programmers call a loop): just put several calls of the same function in a row. But you do need to be careful when you stitch calls together this way: the “seams,” where the repetitions are stitched together, are a common source of trouble. For example, say you want a pattern like this:
(think of the As and Bs as some basic tile commands). It is tempting to use three repetitions of the simpler pattern A B B B A. But this will actually “double up” the As, repeating them where the patterns stitch together:
Another approach would be to just repeating A B B B three times, but then of course you need an extra A at the end to tie it all off:
In the case of Light-Bot programming, you will often find your patterns beginning and ending with a “squat” command to light up the start and end squares. But if you stitch two or more such patterns directly together, the overlapping squats tend to cancel each other out at the seams (recall the toggle behavior when the bot squats on an already-lit square). This sort of thing becomes just a bit tricky: if you just poke at it over and over again, finding a good solution can quickly get tedious The right way to approach the problem is to think clearly and rigorously about the patterns you want. Don't be taken in by the temptation to just poke and tweak until it works: use your head to figure out exactly what you really want first!
Functions generally allow us to reduce the number of tiles we use when we write a script. But although the number of tiles we write is reduced, the number of tiles that actually run during game play will be the same ... or even more, due to the calls themselves, the ƒ1 and ƒ2 tiles.
By using both function, so that one calls the other, we can see even make “patterns within patterns”; this is a powerful technique.
Thought experiment: what is the longest (finite!) sequence of basic moves you can make in a game (ignore the fact that you might go off the board or run into a barrier)?
Hint: how many times can you call a function? How many times can it call a function? How many basic moves or tiles can be in the second function? How many basic moves is that all together?
Thought experiment: what about infinite sequences? Can a function call itself? But then it will never stop ...
Well, sometimes this can actually be useful, since the robot will stop if it accomplishes its goal of lighting the blue squares!
Thought experiment: what is the minimum number of tiles in a script which will cause the robot to do something forever?
Does it count if the robot does nothing forever?
These questions may seem a bit overblown for our little robot game, but similar kinds of questions lead to interesting and difficult questions about the nature and limits of computing, thought of as an abstract, theoretical process. If you have a mathematical or philosophical inclination, ideas like this can be fun to pursue!
We hope that your experiences with Light-Bot have been fun and interesting. If you enjoy the game, you might want to pursue further levels on your own, or even try the Light-Bot 2.0 version. But our main goal for these first exercises has been to give you a quick taste of programming and to get you thinking about it. As we proceed through the class, we’ll be looking at much more powerful and sophisticated kinds of programming, but we hope that some of the ideas you’ve seen here will continue to echo throughout our course of study.
As a final topic, let’s consider how we might apply some of what we’ve glimpsed about programming and computing to the question of where it all fits into a liberal arts education:
We hope you enjoy your introduction to this exciting world!