In order to learn some more about forms, let's create a some forms that create the data for our game world. First of all, our game is going to have some objects in it that the player can pick up and use - let's define those objects:
(def objects '(whiskey-bottle bucket frog chain))
Ok, now let's dissect this line and see what it means: Since a Lisp
compiler always starts reading things in Code Mode and expects
a form, the first symbol,
def, must be a
command. In this case,
the command sets a variable to a value: The variable is
and the value we are setting it to is a list of four
objects. Now, since the list is data (i.e. we don't want the compiler
to try and call a function called
we need to "flip" the compiler into Data Mode when
reading the list.
The single quote in front of the list is the command that tells
the compiler to flip:
def command stands for "define a value". (If
you already know Common Lisp, you might know that an equivalent
command would be "
setf". Clojure actually does not have
Now that we've defined some objects in our world, let's ramp it up a step and define a map of the actual world itself. Here is a picture of what our world looks like:
In this simple game, there will only be three different locations: A
house with a living room and an attic, along with a garden. Let's
define a new variable, called
describes this mini world:
(def game-map (hash-map 'living-room '((you are in the living room of a wizards house - there is a wizard snoring loudly on the couch -) (west door garden) (upstairs stairway attic)) 'garden '((you are in a beautiful garden - there is a well in front of you -) (east door living-room)) 'attic '((you are in the attic of the wizards house - there is a giant welding torch in the corner -) (downstairs stairway living-room))))
This map contains everything important that we'd like to know about our three locations: a unique name for the location (i.e. house, garden, and attic) a short description of what we can see from there (stored in its own list within the bigger list) , plus the where and how of each path into/out of that place. Notice how information-rich this one variable is and how it describes all we need to know but not a thing more - Lispers love to create small, concise pieces of code that leave out any fat and are easy to understand just by looking at them.
Now that we have a map and a bunch of objects, it makes sense to create another variable that says where each of these object is on the map:
(def object-locations (hash-map 'whiskey-bottle 'living-room 'bucket 'living-room 'chain 'garden 'frog 'garden))
Here we have associated each object with a location. Clojure provides
a data structure called a Map.
A Map is created by calling the
with a list of parameters in the order
key1 value1 key2 value2...
game-map variable was also a Map
list - the three keys in that case were living-room,
garden, and attic.
The original tutorial uses association lists. Clojure does not support association lists out-of-the box, instead, it comes with hash-maps which we use as a mapping data structure here.
Now that we have defined our world and the objects in the world, the only thing left to do is describe the location of the player of the game:
(def location 'living-room)
Now let's begin making some game commands!