Now that we can see things in our world, let’s write some code so that we can walk around. The walk
function (not in the functional style) takes a direction and lets us walk there:
(defun walk (direction) (let ((next (find direction (cdr (assoc *location* *edges*)) :key #'cadr))) (if next (progn (setf *location* (car next)) (look)) '(you cannot go that way.))))
First, this function looks up the available walking paths in the *edges*
table, using the current location . This is used by the find
function to locate the path marked with the appropriate direction . (find
searches a list for an item, then returns that found item.) The direction
(such as west
, upstairs
, and so on) will be in the cadr
of each path, so we need to tell find
to match the direction
against the cadr
of all the paths in the list.
We can do this by passing find
a keyword parameter . In Common Lisp, many functions (such as find
) have built-in features that can be accessed by passing in special parameters at the end of the function call. For instance, the following code finds the first item in a list that has the symbol y
in the cadr
location:
> (find 'y '((5 x) (3 y) (7 z)) :key #'cadr)
(3 Y)
A keyword parameter has two parts:
The first is the name (in this case :key
), which begins with a colon. (We’ll discuss the meaning of this colon in more detail in Chapter 7.)
The second is the value, which in this case is #'cadr
.
We use keyword parameters the same way in our walk
function to find the proper path based on the given direction.
Once we have the correct path, we store the result in the variable next
. The if
expression then checks whether next
has a value (the next
variable isn’t nil
). If next
has a value, if
adjusts the player’s position because this is a valid direction . The call to look
retrieves the description for the new location and returns it as a value. If the player chooses an invalid direction, look
will generate an admonishment instead of a new description .
Here’s what our walk
function looks like now:
> (walk 'west)
(YOU ARE IN A BEAUTIFUL GARDEN.
THERE IS A WELL IN FRONT OF YOU.
THERE IS A DOOR GOING EAST FROM HERE.
YOU SEE A CHAIN ON THE FLOOR.
YOU SEE A FROG ON THE FLOOR.)
There’s a quote in front of the direction, since the direction name needs to be written in data mode. It’s kind of awkward to force a player to put a quote in a game command, but the interface we are creating now is intended for easy debugging and development. Heck, it’s almost not even worth calling an “interface,” since we just enter the game commands directly into the REPL. In the next chapter, we’ll create a much nicer interface using a custom REPL designed for playing text games that will take care of this wart.
You could use Lisp macros to create a command in a vanilla Lisp REPL that doesn’t require the quote in front of the direction, so that you could just write (walk west)
, for instance. You’ll learn more about macros in Chapter 16.
18.218.239.182