;; This file contains excerpts from the textbook Concrete ;; Abstractions: An Introduction to Computer Science Using Scheme, by ;; Max Hailperin, Barbara Kaiser, and Karl Knight, Copyright (c) 1998 ;; by Brooks/Cole Publishing Company. This file may not be reproduced ;; or redistributed other than for use with that textbook. ;; Chapter 14: Object-Oriented Programming ;; 14.5 An Application: Adventures in the Imaginary Land of Gack (define-class 'person named-object-class '(place possessions) '(say look-around list-possessions read have-fit move-to go take lose place possessions greet other-people-at-same-place)) (class/set-method! person-class 'init (lambda (this name place) (named-object^init this name) (person/set-place! this place) (person/set-possessions! this '()) (place/gain place this))) (class/set-method! person-class 'say (lambda (this list-of-stuff) (let ((name (person/name this)) (place (person/place this))) (let ((place-name (place/name place))) (display-message (append (list "At" place-name ":" name "says --") list-of-stuff)))))) (class/set-method! person-class 'look-around (lambda (this) (let ((place (person/place this))) (let ((other-items (map named-object/name (delq this (place/contents place)))) (exits (place/exits place))) (person/say this (append '("I see") (verbalize-list other-items "nothing") '("and can go") (verbalize-list exits "nowhere"))))))) (class/set-method! person-class 'list-possessions (lambda (this) (let ((stuff (map thing/name (person/possessions this)))) (person/say this (append '("I have") (verbalize-list stuff "nothing")))))) (class/set-method! person-class 'read (lambda (this scroll) (if (eq? this (scroll/owner scroll)) (scroll/be-read scroll) (display-message (list (person/name this) "does not have" (scroll/name scroll)))))) (class/set-method! person-class 'have-fit (lambda (this) (person/say this '("Yaaaah! I am upset!")))) (class/set-method! person-class 'move-to (lambda (this new-place) (let ((name (person/name this)) (old-place (person/place this)) (possessions (person/possessions this))) (display-message (list name "moves from" (place/name old-place) "to" (place/name new-place))) (place/lose old-place this) (place/gain new-place this) (for-each (lambda (p) (place/lose old-place p) (place/gain new-place p)) possessions) (person/set-place! this new-place) (person/greet this (person/other-people-at-same-place this))))) (class/set-method! person-class 'go (lambda (this direction) (let ((old-place (person/place this))) (let ((new-place (place/neighbor-towards old-place direction))) (if new-place (person/move-to this new-place) (display-message (list "you cannot go" direction "from" (place/name old-place)))))))) (class/set-method! person-class 'take (lambda (this thing) (if (eq? this (thing/owner thing)) (display-message (list (person/name this) "already has" (thing/name thing))) (begin (if (thing/owned? thing) (let ((owner (thing/owner thing))) (person/lose owner thing) (person/have-fit owner)) 'unowned) (thing/become-owned-by thing this) (person/set-possessions! this (cons thing (person/possessions this))) (person/say this (list "I take" (thing/name thing))))))) (class/set-method! person-class 'lose (lambda (this thing) (if (not (eq? this (thing/owner thing))) (display-message (list (person/name this) "doesn't have" (thing/name thing))) (begin (thing/become-unowned thing) (person/set-possessions! this (delq thing (person/possessions this))) (person/say this (list "I lose" (thing/name thing))))))) (class/set-method! person-class 'place (lambda (this) (person/get-place this))) (class/set-method! person-class 'possessions (lambda (this) (person/get-possessions this))) (class/set-method! person-class 'greet (lambda (this people) (if (not (null? people)) (person/say this (cons "Hi" (verbalize-list (map person/name people) "no one"))) 'no-one-to-greet))) (class/set-method! person-class 'other-people-at-same-place (lambda (this) (delq this (filter person? (place/contents (person/place this))))))