Building the Nodes for Congestion City

Now we’ll build an alist for the nodes in our city. These nodes may contain the Wumpus or the Glowworms, or they might contain various clues, such as blood, lights, or sirens.

Most of the clues in our game are based on proximity to another node, so we need to write some functions that tell us if two nodes are one node apart in the city graph. The neighbors function looks up the node’s neighbors using the alist of edges. If the second node is in that list, we know we’re one away.

(defun neighbors (node edge-alist)
 (mapcar #'car (cdr (assoc node edge-alist))))

(defun within-one (a b edge-alist)
 (member b (neighbors a edge-alist)))

First, this function looks up the first node (a) in the alist of edges with neighbors. Then it uses member to see if the other node (b) is among these nodes.

The blood stain clues for the Wumpus can also be seen from two nodes away. We can write a second function for checking two nodes like this:

(defun within-two (a b edge-alist)
   (or (within-one a b edge-alist)
        (some (lambda (x)
               (within-one x b edge-alist))
             (neighbors a edge-alist))))

First, we check if we are within one node of our goal , since if we’re within one, we’re also within two. Next, we extract all the nodes that are one away (similar to what we did in the within-one function). Finally, we check if any of these new nodes are within one , which would make them within two of the original node.

Now that we have those utility functions, let’s write the function that builds the final node alist (basically, the final map of our city.) Here’s the listing:

(defun make-city-nodes (edge-alist)
   (let ((wumpus (random-node))
         (glow-worms (loop for i below *worm-num*
                            collect (random-node))))
     (loop for n from 1 to *node-num*
         collect (append (list n)
                         (cond ((eql n wumpus) '(wumpus))
                               ((within-two n wumpus edge-alist) '(blood!)))
                         (cond ((member n glow-worms)
                                 '(glow-worm))
                               ((some (lambda (worm)
                                         (within-one n worm edge-alist))
                                       glow-worms)
                                 '(lights!)))
                         (when (some #'cdr (cdr (assoc n edge-alist)))
                            '(sirens!))))))

The make-city-nodes function first picks random nodes for the Wumpus and the Glowworms , and then it uses loop to run through the node numbers. As it runs through the nodes, it builds a list describing each node in the city, appended together from various sources . By using append, each part of the code that describes these nodes (and is within the body of the append) can choose to add zero, one, or multiple items to the description, creating its own child lists with zero, one, or multiple items.

At the front of the list, we put the node name, n . If the Wumpus is at the current node, we add the word Wumpus (but wrapped in a list, as we just described). If we’re within two nodes of the Wumpus, we show its blood . If the node has a Glowworm gang, we show it next , and if the Glowworm gang is one node away, we show its lights . Finally, if an edge from the node contains cops, we indicate that sirens can be heard .

To check for the sirens clue, we simply grab the edges with (cdr (assoc n edges)) and see if some of these nodes have a value in the cdr. The 'cops symbol would be attached to the edges at the cdr. Since we have only one data point for edges in this game, looking for the presence of a cdr is an adequate check for the presence of cops. For example, if we use our earlier example of an alist with cops on it:

((1 (2)) (2 (1) (3 COPS)) (3 (2 COPS)))

You can see that if an edge in the list has cops, such as here , the cdr will lead to a non-nil value. An edge without cops will have a cdr that is nil.

image with no caption
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.14.144.216