On Oct 2, 2005, at 8:35 AM, Jim Menard wrote:

> Boy, was this fun. My solution, RADS, is at
> <http://www.io.com/~jimm/rubyquiz/quiz49/>.

That is beyond awesome!  I've been reading the PAWS source thinking  
of porting it, but you have a very interesting start here.

My solution is below.  Again, I took the direct approach of a line  
for line translation.  So, in my code you will see the Lisp, followed  
by my Ruby translation.  It was interesting making lines like:

 > walk east

work in irb.  It even came out cleaner than the Lisp version of  
"(walk east)".

Enjoy.

James Edward Gray II

(setf *objects* '(whiskey-bottle bucket frog chain))
### ^ Lisp >>> Ruby v ###
$objects = %w{whiskey_bottle bucket frog chain}

(setf *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))))
### ^ Lisp >>> Ruby v ###
$map = { "living_room" => [ "You are in the living_room of a wizard's  
house. There is a wizard snoring loudly on the couch.",
                             %w{west door garden},
                             %w{upstairs stairway attic} ],
          "garden"      => [ "You are in a beautiful garden. There is  
a well in front of you.",
                             %w{east door living_room} ],
          "attic"       => [ "You are in the attic of the wizard's  
house. There is a giant welding torch in the corner.",
                             %w{downstairs stairway living_room} ] }

(setf *object-locations* '((whiskey-bottle living-room)
                            (bucket living-room)
                            (chain garden)
                            (frog garden)))
### ^ Lisp >>> Ruby v ###
$object_locations = { "whiskey_bottle" => "living_room",
                       "bucket"         => "living_room",
                       "chain"          => "garden",
                       "frog"           => "garden" }

(setf *location* 'living-room)
### ^ Lisp >>> Ruby v ###
$location = "living_room"

(defun describe-location (location map)
   (second (assoc location map)))
### ^ Lisp >>> Ruby v ###
def describe_location( location, map )
   map[location].first
end

(describe-location 'living-room *map*)
### ^ Lisp >>> Ruby v ###
describe_location "living_room", $map

(defun describe-path (path)
   `(there is a ,(second path) going ,(first path) from here.))
### ^ Lisp >>> Ruby v ###
def describe_path( path )
   "There is a #{path[1]} going #{path[0]} from here."
end

(describe-path '(west door garden))
### ^ Lisp >>> Ruby v ###
describe_path %w{west door garden}

(defun describe-paths (location map)
   (apply #'append (mapcar #'describe-path (cddr (assoc location  
map)))))
### ^ Lisp >>> Ruby v ###
def describe_paths( location, map )
   map[location][1..-1].map { |p| describe_path(p) }.join("  ")
end

(describe-paths 'living-room *map*)
### ^ Lisp >>> Ruby v ###
describe_paths "living_room", $map

(defun is-at (obj loc obj-loc)
   (eq (second (assoc obj obj-loc)) loc))
### ^ Lisp >>> Ruby v ###
def is_at?( object, location, object_locations )
   location == object_locations[object]
end

(is-at 'whiskey-bottle 'living-room *object-locations*)
### ^ Lisp >>> Ruby v ###
is_at? "whiskey_bottle", "living_room", $object_locations

(defun describe-floor (loc objs obj-loc)
   (apply #'append (mapcar (lambda (x)
                             `(you see a ,x on the floor.))
                           (remove-if-not (lambda (x)
                                            (is-at x loc obj-loc))
                                          objs))))
### ^ Lisp >>> Ruby v ###
def describe_floor( location, object_locations )
   object_locations.select { |obj, loc| loc == location }.map do | 
obj, loc|
     "You see a #{obj} on the floor."
   end.join("  ")
end

(describe-floor 'living-room *objects* *object-locations*)
### ^ Lisp >>> Ruby v ###
describe_floor "living_room", $object_locations

(defun look ()
   (append (describe-location *location* *map*)
           (describe-paths *location* *map*)
           (describe-floor *location* *objects* *object-locations*)))
### ^ Lisp >>> Ruby v ###
def look
   [ describe_location($location, $map),
     describe_paths($location, $map),
     describe_floor($location, $object_locations) ].join("  ").strip
end

(look)
### ^ Lisp >>> Ruby v ###
look

(defun walk-direction (direction)
   (let ((next (assoc direction (cddr (assoc *location* *map*)))))
     (cond (next (setf *location* (third next)) (look))
           (t '(you cant go that way.)))))
### ^ Lisp >>> Ruby v ###
def walk_direction( direction )
   if to = $map[$location][1..-1].assoc(direction)
     $location = to.last
     look
   else
     "You can't go that way."
   end
end

(walk-direction 'west)
### ^ Lisp >>> Ruby v ###
walk_direction "west"

(defmacro defspel (&rest rest) `(defmacro ,@rest))
### ^ Lisp >>> Ruby v ###
$stringify = %w{west east upstairs downstairs}
def method_missing( method, *args, &block )
   if $stringify.include? method.to_s
     method.to_s
   else
     "I don't know the word '#{method}'."
   end
end

(defspel walk (direction)
   `(walk-direction ',direction)
### ^ Lisp >>> Ruby v ###
alias walk walk_direction

(walk east)
### ^ Lisp >>> Ruby v ###
walk east

(defun pickup-object (object)
   (cond ((is-at object *location* *object-locations*) (push (list  
object 'body) *object-locations*)
                                                       `(you are now  
carrying the ,object))
         (t '(you cannot get that.))))
### ^ Lisp >>> Ruby v ###
def pickup_object( object )
   if is_at? object, $location, $object_locations
     $object_locations[object] = "body"
     "You are now carrying #{object}."
   else
     "You cannot get that."
   end
end

(defspel pickup (object)
   `(pickup-object ',object))
### ^ Lisp >>> Ruby v ###
$stringify.push(*$objects)
alias pickup pickup_object

(pickup whiskey-bottle)
### ^ Lisp >>> Ruby v ###
pickup whiskey_bottle

(defun inventory ()
   (remove-if-not (lambda (x)
                    (is-at x 'body *object-locations*))
                  *objects*))
### ^ Lisp >>> Ruby v ###
def inventory
   $objects.select { |obj| $object_locations[obj] == "body" }
end

(defun have (object)
   (member object (inventory)))
### ^ Lisp >>> Ruby v ###
def have?( object )
   inventory.include? object
end

(setf *chain-welded* nil)
### ^ Lisp >>> Ruby v ###
$chain_welded = nil

(defun weld (subject object)
   (cond ((and (eq *location* 'attic)
               (eq subject 'chain)
               (eq object 'bucket)
               (have 'chain)
               (have 'bucket)
               (not *chain-welded*))
          (setf *chain-welded* 't)
          '(the chain is now securely welded to the bucket.))
         (t '(you cannot weld like that.))))
### ^ Lisp >>> Ruby v ###
def weld( *objects )
   if $location == "attic" and not $chain_welded and
      objects.all? { |obj| have? obj } and objects.sort == %w{bucket  
chain}
     $chain_welded = true
     "The chain is now securely welded to the bucket."
   else
     "You cannot weld like that."
   end
end

(weld 'chain 'bucket)
### ^ Lisp >>> Ruby v ###
weld "chain", "bucket"

(setf *bucket-filled* nil)
### ^ Lisp >>> Ruby v ###
$bucket_filled = nil

(defun dunk (subject object)
   (cond ((and (eq *location* 'garden)
               (eq subject 'bucket)
               (eq object 'well)
               (have 'bucket)
               *chain-welded*)
          (setf *bucket-filled* 't) '(the bucket is now full of water))
         (t '(you cannot dunk like that.))))
### ^ Lisp >>> Ruby v ###
def dunk( *objects )
   if $location == "garden" and $chain_welded and objects.sort == %w 
{bucket well}
     $bucket_filled = true
     "The bucket is now full of water."
   else
     "You cannot dunk like that."
   end
end

(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 cant ,',command like that.)))))
### ^ Lisp >>> Ruby v ###
def game_action( action, subject, object, location, &block )
   $stringify << object unless $stringify.include? object
   self.class.send(:define_method, action) do |sub, obj|
     begin
       if $location == location and
          subject == sub and object == obj and have?(subject)
         block[sub, obj]
       else
         raise
       end
     rescue
       "You can't #{action} like that."
     end
   end
end

(game-action weld chain bucket attic
              (cond ((and (have 'bucket) (setf *chain-welded* 't))
                     '(the chain is now securely welded to the bucket.))
                    (t '(you do not have a bucket.))))
### ^ Lisp >>> Ruby v ###
game_action(*%w{weld chain bucket attic}) do |subject, object|
   have?(object) or raise
   $chain_welded = true
   "The chain is now securely welded to the bucket."
end

(weld chain bucket)
### ^ Lisp >>> Ruby v ###
weld chain, bucket

(game-action dunk bucket well garden
              (cond (*chain-welded* (setf *bucket-filled* 't) '(the  
bucket is now full of water))
                    (t '(the water level is too low to reach.))))
### ^ Lisp >>> Ruby v ###
game_action(*%w{dunk bucket well garden}) do |subject, object|
   $chain_welded or raise
   $bucket_filled = true
   "The bucket is now full of water."
end

(game-action splash bucket wizard living-room
              (cond ((not *bucket-filled*) '(the bucket has nothing  
in it.))
                    ((have 'frog) '(the wizard awakens and sees that  
you stole his frog.
                                    he is so upset he banishes you to  
the
                                    netherworlds- you lose! the end.))
                    (t '(the wizard awakens from his slumber and  
greets you warmly.
                         he hands you the magic low-carb donut- you  
win! the end.))))
### ^ Lisp >>> Ruby v ###
game_action(*%w{splash bucket wizard living_room}) do |subject, object|
   $bucket_filled or raise
   if have? "frog"
     "The wizard awakens and sees that you stole his frog.  " +
     "He is so upset he banishes you to the netherworlds--you lose!   
The end."
   else
     "The wizard awakens from his slumber and greets you warmly.  " +
     "He hands you the magic low-carb donut--you win!  The end."
   end
end