~ $ cd teaching/adventure && cat README.md
Sixty-four rooms
In the autumn of 2007 I taught the lab of Introducció als Ordinadors at the UPC: first year, first term, first programs in C. The lab was a text adventure. It is small — one file of C, six hundred lines, and three text files it reads at the start — and it is playable, here, exactly as it was:
===== Bienvenida =====
Bienvenido a este juego de aventura.
Esta es la habitacion de bienvenida, donde aprenderas a moverte.
Los comandos son:
'norte',
'sur',
'este',
'oeste'.
Prueba de ir a la siguiente habitacion al 'este', y volver al 'oeste'.
Hay: diario
Salidas: este.
(0,0)| 16>
The words are the game's, in Spanish, as they were written for the class: norte, sur, este, oeste, coger, atacar. The English ones work too. You start in the south-west corner with sixteen points of life and nothing in your hands, and the pantry is one room away through a door you have no key for. The map fills in as you go.
Four schemas, and nothing else
A first-year student cannot yet hold a program in their head. What they can hold is a recipe. So the course taught four schemas and the lab was designed so that four schemas were all it took:
traversal, without a mark search, without a mark
first(); found = 0;
while (more()) { first();
e = get(); while (more() && !found) {
treat(e); e = get();
next(); if (is_it(e)) { treat(e); found = 1; }
} next();
finish(); }
finish();
and the same two again with a mark, for a sequence that ends in a sentinel rather than a count — a file, a line ending in a full stop. Every problem in the lab is one of the four, with first, more, get, treat and is_it filled in for the case at hand: reading the items file is a traversal with a mark (end of file); finding the monster a room names is a search over a list; the game loop itself is a traversal with a mark, the mark being the word salir. The theory sheet said so in as many words: decide which of the four it is, then replace each operation for the case.
The data structures followed the same rule. A list is an array and a count. A room is a record: a name, a description, four exits, what it holds. The world is a matrix of rooms, eight by eight, so that north is i + 1 and east is j + 1 and there is no graph to traverse, only a grid to index.
The map came first
I drew the map on squared paper before anything else, so that it would be worth exploring: the house in the south-west corner, the orchard and the farm along the south, the river across the middle, the forest to the north-east and the caves to the north-west, and the pantry — the goal — one locked door from where you start. Then I typed it into habitaciones.txt, one room at a time, each with its four exits and what it holds.
Everything the game knows is in those three files, and a student could change any of it without touching the C: add a room, move a monster, invent a weapon. The program reads them with fscanf and a format string, which is its own small lesson in what a sequence is.
What it does not do
Kill you. The check on the player's life is in the source, commented out: a first-year lab is not the place to lose. So the numbers were never balanced for survival, and the last fight, as it happens, costs exactly the sixteen points there are. A door you open stays open only from the side you opened it. And one line of the rooms file had a typo that left the bridge in the forest without its gnome; here the gnome is on his bridge, which is the one thing changed.