Let's try our new command:
|
(weld 'chain 'bucket)
|
==> (you cannot weld like that -)
|
Oops... we don't have a bucket or chain, do we? ...and there's
no welding machine around... oh well...
|
Now let's create a command for dunking the chain and bucket in
the well:
|
(setq bucket-filled nil)
(defun dunk (subject object)
(cond ((and (eq location 'garden)
(eq subject 'bucket)
(eq object 'well)
(have 'bucket)
chain-welded)
(setq bucket-filled 't) '(the bucket is now full of water))
(t '(you cannot dunk like that -))))
|
Now if you paid attention, you probably noticed that this
command looks a lot like the weld command...
Both commands need to check the location, subject, and object,
but they're different enough that we can't combine the
similarities into a single function. Too bad...
|
...but since this is Lisp, we can do more than just write
functions, we can cast SPELs! Let's create the following SPEL:
|
(defspel game-action (command subj obj place &rest rest)
`(defspel ,command (subject object)
`(cond ((and (eq location ',',place)
(eq ',subject ',',subj)
(eq ',object ',',obj)
(have ',',subj))
,@',rest)
(t '(i cannot ,',command like that -)))))
|
Notice how ridiculously complex this SPEL is - It has more
quotes, backquotes, commas and other weird symbols than you can
shake a list at. More than that, it is a SPEL that actually
casts another SPEL! Even experienced Lisp programmers
would have to put some thought into creating a monstrosity like
this (and in fact they would consider this SPEL to be inelegant
and would go through some extra esoteric steps to make it
better-behaved that we won't worry about here...)
|
<< begin
< previous -
next >
end >>
|