(define make-room (lambda (name) (local ; local state of room object ((define thing #f) ; by default, nothing in room (define east #f) ; by default, no adjoining rooms (define west #f) ; ... (define north #f) ; ... (define south #f)) ; ... (lambda (msg) ; start of object returned (cond ((null? msg) 'badmessage) ; initialize things and adjoining rooms ((eq? (car msg) 'set-thing!) (set! thing (car (cdr msg)))) ((eq? (car msg) 'set-east!) (set! east (car (cdr msg)))) ((eq? (car msg) 'set-west!) (set! west (car (cdr msg)))) ((eq? (car msg) 'set-north!) (set! north (car (cdr msg)))) ((eq? (car msg) 'set-south!) (set! south (car (cdr msg)))) ((eq? (car msg) 'name) name) ; look at surroundings ((eq? (car msg) 'observe-thing) thing) ((eq? (car msg) 'observe-east) east) ((eq? (car msg) 'observe-west) west) ((eq? (car msg) 'observe-north) north) ((eq? (car msg) 'observe-south) south) ((eq? (car msg) 'take-thing) (local ((define x thing)) (set! thing #f) x)) (else 'badmessage)))))) (define make-person (lambda (initial-room) (local ((define thing #f) ; initially, nothing carried (define room initial-room)) (lambda (msg) ; start of object returned (cond ((null? msg) 'badmessage) ; initialize thing and room ((eq? (car msg) 'set-thing!) (set! thing (car (cdr msg)))) ((eq? (car msg) 'set-room!) (set! room (car (cdr msg)))) ; look around ((eq? (car msg) 'look-room) (if room (local ((define eastroom (room (list 'observe-east))) (define westroom (room (list 'observe-west))) (define northroom (room (list 'observe-north))) (define southroom (room (list 'observe-south)))) (list (room (list 'observe-thing)) (if eastroom (eastroom (list 'name)) #f) (if westroom (westroom (list 'name)) #f) (if northroom (northroom (list 'name)) #f) (if southroom (southroom (list 'name)) #f))) 'badmessage)) ((eq? (car msg) 'look-self) thing) ; move, if possible ((eq? (car msg) 'go-east) (if (and room (room (list 'observe-east))) (set! room (room (list 'observe-east))) 'badmessage)) ((eq? (car msg) 'go-west) (if (and room (room (list 'observe-west))) (set! room (room (list 'observe-west))) 'badmessage)) ((eq? (car msg) 'go-north) (if (and room (room (list 'observe-north))) (set! room (room (list 'observe-north))) 'badmessage)) ((eq? (car msg) 'go-south) (if (and room (room (list 'observe-south))) (set! room (room (list 'observe-south))) 'badmessage)) ; get the room's thing if any, dropping our current thing ((eq? (car msg) 'get-thing) (if (and room (room (list 'observe-thing))) (local ((define temp-thing (room (list 'observe-thing)))) (room (list 'set-thing! thing)) (set! thing temp-thing)) 'badmessage) (else 'badmessage))))))) (define room1 (make-room 'joes-office)) (define room2 (make-room 'johns-office)) (define room3 (make-room 'PL210)) (define room4 (make-room 'CS-office)) (room1 (list 'set-thing! 'ball)) (room2 (list 'set-thing! 'key)) (room4 (list 'set-thing! 'stapler)) (room1 (list 'set-east! room3)) (room1 (list 'set-north! room2)) (room2 (list 'set-south! room1)) (room2 (list 'set-west! room4)) (room3 (list 'set-south! room1)) (room3 (list 'set-north! room2)) (room4 (list 'set-east! room2)) (room4 (list 'set-west! room1)) (room4 (list 'set-north! room1)) (define joe (make-person room1)) (define john (make-person room2))