;; 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 'place named-object-class '(neighbor-map ; pairs: car = direction, cdr = neighbor contents) ; people and things '(exits neighbors neighbor-towards add-new-neighbor gain lose contents)) (class/set-method! place-class 'init (lambda (this name) (named-object^init this name) (place/set-neighbor-map! this '()) (place/set-contents! this '()))) (class/set-method! place-class 'exits (lambda (this) (map car (place/get-neighbor-map this)))) (class/set-method! place-class 'neighbors (lambda (this) (map cdr (place/get-neighbor-map this)))) (class/set-method! place-class 'neighbor-towards (lambda (this direction) (let ((p (assq direction (place/get-neighbor-map this)))) (if (not p) #f (cdr p))))) (class/set-method! place-class 'add-new-neighbor (lambda (this direction new-neighbor) (let ((neighbor-map (place/get-neighbor-map this))) (if (assq direction neighbor-map) (display-message (list "there is already a neighbor" direction "from" (place/name this))) (place/set-neighbor-map! this (cons (cons direction new-neighbor) neighbor-map)))))) (class/set-method! place-class 'gain (lambda (this new-item) (let ((contents (place/contents this))) (if (memq new-item contents) (display-message (list (named-object/name new-item) "is already at" (place/name this))) (place/set-contents! this (cons new-item contents)))))) (class/set-method! place-class 'lose (lambda (this item) (let ((contents (place/contents this))) (if (not (memq item contents)) (display-message (list (named-object/name item) "is not at" (place/name this))) (place/set-contents! this (delq item contents)))))) (class/set-method! place-class 'contents (lambda (this) (place/get-contents this)))