about summary refs log tree commit diff stats
path: root/js/games/nluqo.github.io/~bh/61a-pages/Volume1/Project3
diff options
context:
space:
mode:
authorelioat <elioat@tilde.institute>2023-08-23 07:52:19 -0400
committerelioat <elioat@tilde.institute>2023-08-23 07:52:19 -0400
commit562a9a52d599d9a05f871404050968a5fd282640 (patch)
tree7d3305c1252c043bfe246ccc7deff0056aa6b5ab /js/games/nluqo.github.io/~bh/61a-pages/Volume1/Project3
parent5d012c6c011a9dedf7d0a098e456206244eb5a0f (diff)
downloadtour-562a9a52d599d9a05f871404050968a5fd282640.tar.gz
*
Diffstat (limited to 'js/games/nluqo.github.io/~bh/61a-pages/Volume1/Project3')
-rw-r--r--js/games/nluqo.github.io/~bh/61a-pages/Volume1/Project3/adv-world.scm83
-rw-r--r--js/games/nluqo.github.io/~bh/61a-pages/Volume1/Project3/adv.txt718
-rw-r--r--js/games/nluqo.github.io/~bh/61a-pages/Volume1/Project3/obj.scm279
-rw-r--r--js/games/nluqo.github.io/~bh/61a-pages/Volume1/Project3/small-world.scm28
4 files changed, 1108 insertions, 0 deletions
diff --git a/js/games/nluqo.github.io/~bh/61a-pages/Volume1/Project3/adv-world.scm b/js/games/nluqo.github.io/~bh/61a-pages/Volume1/Project3/adv-world.scm
new file mode 100644
index 0000000..bc4eb8c
--- /dev/null
+++ b/js/games/nluqo.github.io/~bh/61a-pages/Volume1/Project3/adv-world.scm
@@ -0,0 +1,83 @@
+;;;  Data for adventure game.  This file is adv-world.scm
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; setting up the world
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(define Soda (instantiate place 'Soda))
+(define BH-Office (instantiate place 'BH-Office))
+(define MJC-Office (instantiate place 'MJC-Office))
+(define art-gallery (instantiate place 'art-gallery))
+(define Pimentel (instantiate place 'Pimentel))
+(define 61A-Lab (instantiate place '61A-Lab))
+(define Sproul-Plaza (instantiate place 'Sproul-Plaza))
+(define Telegraph-Ave (instantiate place 'Telegraph-Ave))
+(define Noahs (instantiate place 'Noahs))
+(define Intermezzo (instantiate place 'Intermezzo))
+(define s-h (instantiate place 'sproul-hall))
+
+
+(can-go Soda 'up art-gallery)
+(can-go art-gallery 'down Soda)
+(can-go art-gallery 'west BH-Office)
+(can-go BH-Office 'east art-gallery)
+(can-go art-gallery 'east MJC-Office)
+(can-go MJC-office 'west art-gallery)
+(can-go Soda 'south Pimentel)
+(can-go Pimentel 'north Soda)
+(can-go Pimentel 'south 61A-Lab)
+(can-go 61A-Lab 'north Pimentel)
+(can-go 61A-Lab 'west s-h)
+(can-go s-h 'east 61A-Lab)
+(can-go Sproul-Plaza 'east s-h)
+(can-go s-h 'west Sproul-Plaza)
+(can-go Sproul-Plaza 'north Pimentel)
+(can-go Sproul-Plaza 'south Telegraph-Ave)
+(can-go Telegraph-Ave 'north Sproul-Plaza)
+(can-go Telegraph-Ave 'south Noahs)
+(can-go Noahs 'north Telegraph-Ave)
+(can-go Noahs 'south Intermezzo)
+(can-go Intermezzo 'north Noahs)
+
+;; Some people.
+; MOVED above the add-entry-procedure stuff, to avoid the "The computers
+; seem to be down" message that would occur when hacker enters 61a-lab
+; -- Ryan Stejskal
+
+(define Brian (instantiate person 'Brian BH-Office))
+(define hacker (instantiate person 'hacker 61A-lab))
+(define nasty (instantiate thief 'nasty sproul-plaza))
+
+(define (sproul-hall-exit)
+   (error "You can check out any time you'd like, but you can never leave"))
+
+(define (bh-office-exit)
+  (print "What's your favorite programming language?")
+  (let ((answer (read)))
+    (if (eq? answer 'scheme)
+	(print "Good answer, but my favorite is Logo!")
+	(begin (newline) (bh-office-exit)))))
+    
+
+(ask s-h 'add-entry-procedure
+ (lambda () (print "Miles and miles of students are waiting in line...")))
+(ask s-h 'add-exit-procedure sproul-hall-exit)
+(ask BH-Office 'add-exit-procedure bh-office-exit)
+(ask Noahs 'add-entry-procedure
+ (lambda () (print "Would you like lox with it?")))
+(ask Noahs 'add-exit-procedure
+ (lambda () (print "How about a cinnamon raisin bagel for dessert?")))
+(ask Telegraph-Ave 'add-entry-procedure
+ (lambda () (print "There are tie-dyed shirts as far as you can see...")))
+(ask 61A-Lab 'add-entry-procedure
+ (lambda () (print "The computers seem to be down")))
+(ask 61A-Lab 'add-exit-procedure
+ (lambda () (print "The workstations come back to life just in time.")))
+
+;; Some things.
+
+(define bagel (instantiate thing 'bagel))
+(ask Noahs 'appear bagel)
+
+(define coffee (instantiate thing 'coffee))
+(ask Intermezzo 'appear coffee)
diff --git a/js/games/nluqo.github.io/~bh/61a-pages/Volume1/Project3/adv.txt b/js/games/nluqo.github.io/~bh/61a-pages/Volume1/Project3/adv.txt
new file mode 100644
index 0000000..755f2ed
--- /dev/null
+++ b/js/games/nluqo.github.io/~bh/61a-pages/Volume1/Project3/adv.txt
@@ -0,0 +1,718 @@
+Project:  Write an adventure game.  We'll provide most of the program.  You
+will mostly make modification and some additions.
+
+This project is designed to be done by two people working in parallel, then
+combining your results into one finished product.  (Hereafter the two partners
+are called Person A and Person B.)  But you will combine your work to hand in
+a single report for your group.
+
+The project begins with two exercises that everyone should do; these
+exercises do not require new programming, but rather familiarize you
+with the overall structure of the program as we've provided it.  After
+that, each person has separate exercises.  There is one final exercise
+for everyone that requires the two partners' work to be combined.
+(Therefore, you should probably keep notes about all of the procedures
+that you've modified during the project, so you can notice the ones that
+both partners modified independently.)
+
+This is a two-week project.  Each week, your group should
+hand in one paper (not one per person) including a listing of your modified
+adv.scm program with the modifications highlighted, and a transcript of the
+testing of your work.  Indicate on the paper which of you is person A and
+which is person B.
+
+Scoring:  Each person works on nine problems.  Three of these (numbers
+1, 2, and 9) are common to the two partners; the others are separate.
+You hand in a single solution to each problem.  Both partners get
+the points awarded to the group for problems 1, 2, and 9; each
+person gets the points for his or her own problems 3 through 8.  This means
+that your score for the project is mostly based on your individual work but
+also relies partly on the other member of your group.  For the first two
+problems, you could get away with letting your partner do the
+work, but you shouldn't because those problems are necessary to help you
+understand the structure of the entire project.  Problem 9 requires that both
+partners have already done their separate work, and meet together to
+understand each other's solutions, so probably nobody will get credit for it
+unless both have done their jobs.
+
+(Acknowledgement:  This assignment is loosely based on an MIT homework
+assignment in their version of this course.  But since this is Berkeley we've
+changed it to be politically correct; instead of killing each other, the
+characters go around eating gourmet food all the time.  N.B.:  Unless you
+are a diehard yuppie you may feel that eating gourmet food does not express
+appropriate sensitivity to the plight of the homeless.  But it's a start.)
+
+In this laboratory assignment, we will be exploring two key ideas: the
+simulation of a world in which objects are characterized by a set of state
+variables, and the use of message passing as a programming technique for
+modularizing worlds in which objects interact.
+
+OBJECT-ORIENTED PROGRAMMING is becoming an extremely popular methodology for
+any application that involves interactions among computational entities.
+Examples:
+
+	-- operating systems (processes as objects)
+	-- window systems (windows as objects)
+	-- games (asteroids, spaceships, gorillas as objects)
+	-- drawing programs (shapes as objects)
+
+
+GETTING STARTED
+To start, copy the following five files into your directory:
+   ~cs61a/lib/obj.scm           The object-oriented system
+   ~cs61a/lib/adv.scm           The adventure game program
+   ~cs61a/lib/tables.scm	An ADT you'll need for parts A5 and B4
+   ~cs61a/lib/adv-world.scm     The specific people, places, and things
+   ~cs61a/lib/small-world.scm   A smaller world you can use for debugging
+
+To work on this project, you must load these files into Scheme in the
+correct order: obj.scm first, then adv.scm and tables.scm when you're using
+that, and finally the particular world you're using, either adv-world.scm or
+small-world.scm.  The work you are asked to do refers to adv-world.scm;
+small-world.scm is provided in case you'd prefer to debug some of your
+procedures in a smaller world that may be less complicated to remember and
+also faster to load.
+
+The reason the adventure game is divided into adv.scm (containing the
+definitions of the object classes) and adv-world.scm (containing the
+specific instances of those objects in Berkeley) is that when you change
+something in adv.scm you may need to reload the entire world in order for
+your changed version to take effect.  Having two files means that you don't
+also have to reload the first batch of procedures.
+
+
+In this program there are three classes: THING, PLACE, and PERSON.
+
+Here are some examples selected from adv-world.scm:
+
+;;; construct the places in the world
+(define Soda (instantiate place 'Soda))
+(define BH-Office (instantiate place 'BH-Office))
+(define art-gallery (instantiate place 'art-gallery))
+(define Pimentel (instantiate place 'Pimentel))
+(define 61A-Lab (instantiate place '61A-Lab))
+(define Sproul-Plaza (instantiate place 'Sproul-Plaza))
+(define Telegraph-Ave (instantiate place 'Telegraph-Ave))
+(define Noahs (instantiate place 'Noahs))
+(define Intermezzo (instantiate place 'Intermezzo))
+(define s-h (instantiate place 'sproul-hall))
+
+;;; make some things and put them at places
+(define bagel (instantiate thing 'bagel))
+(ask Noahs 'appear bagel)
+
+(define coffee (instantiate thing 'coffee))
+(ask Intermezzo 'appear coffee)
+
+;;; make some people
+(define Brian (instantiate person 'Brian BH-Office))
+(define hacker (instantiate person 'hacker Pimentel))
+
+;;; connect places in the world
+
+(can-go Soda 'up art-gallery)
+(can-go art-gallery 'west BH-Office)
+(can-go Soda 'south Pimentel)
+
+Having constructed this world, we can now interact with it by sending
+messages to objects.  Here is a short example.
+
+; We start with the hacker in Pimentel.
+
+> (ask Pimentel 'exits)
+(NORTH SOUTH)
+> (ask hacker 'go 'north)
+HACKER moved from PIMENTEL to SODA
+
+
+We can put objects in the different places, and the people can then take the
+objects:
+
+> (define Jolt (instantiate thing 'Jolt))
+JOLT
+> (ask Soda 'appear Jolt)
+APPEARED
+> (ask hacker 'take Jolt)
+HACKER took JOLT
+TAKEN
+
+You can take objects away from other people, but the management is not
+responsible for the consequences...  (Too bad this is a fantasy game, and
+there aren't really vending machines in Soda that stock Jolt.)
+
+PART I:
+
+The first two exercises in this part should be done by everyone -- that is,
+everyone should actually sit in front of a terminal and do it!  It's okay to
+work in pairs as long as you all really know what's going on by the time
+you're finished.  (Nevertheless, you should only hand in one solution, that
+both agree about.)  The remaining exercises have numbers like "A3"
+which means exercise 3 for Person A.
+
+After you've done the work separately, you should meet together
+to make sure that you each understands what the other person did, because
+the second week's work depends on all of the first week's work.  You can
+do the explaining while you're merging the two sets of modifications into
+one adv.scm file to hand in.
+
+1.  Create a new person to represent yourself.  Put yourself in a new place
+called Dormitory (or wherever you live) and connect it to campus so that you
+can get there from here.  Create a place called Kirin, north of Soda.
+(It's actually on Solano Avenue.)  Put a thing called Potstickers there.
+Then give the necessary commands to move your character to Kirin, take
+the Potstickers, then move yourself to where Brian is, put down the
+Potstickers, and have Brian take them. Then go back to the lab and get back
+to work. (There is no truth to the rumor that you'll get an A in the course
+for doing this in real life!)  All this is just to ensure that you know how
+to speak the language of the adventure program.
+
+LIST ALL THE MESSAGES THAT ARE SENT DURING THIS EPISODE.  It's a good idea
+to see if you can work this out in your head, at least for some of the
+actions that take place, but you can also trace the ASK procedure to get
+a complete list.  You don't have to hand in this listing of messages.  (Do
+hand in a transcript of the episode without the tracing.)  The point is that
+you should have a good sense of the ways in which the different objects send
+messages back and forth as they do their work.
+
+[Tip:  we have provided a MOVE-LOOP procedure that you may find useful as
+an aid in debugging your work.  You can use it to move a person repeatedly.]
+
+
+2.  It is very important that you think about and understand the kinds of
+objects involved in the adventure game.  Please answer the following questions:
+
+2A.  What kind of thing is the value of variable BRIAN?
+
+Hint:  What is returned by scheme in the following situation:
+     You type:     > BRIAN
+
+
+2B.   List all the messages that a PLACE understands.  (You might want to
+maintain such a list for your own use, for every type of object, to help
+in the debugging effort.)
+
+
+2C.   We have been defining a variable to hold each object in our world.
+For example, we defined bagel by saying:
+
+     (define bagel (instantiate thing 'bagel))
+
+This is just for convenience.  Every object does not have to have a
+top-level definition.  Every object DOES have to be constructed and
+connected to the world.  For instance, suppose we did this:
+
+> (can-go Telegraph-Ave 'east (instantiate place 'Peoples-Park))
+
+;;; assume BRIAN is at Telegraph
+> (ask Brian 'go 'east)
+
+What is returned by the following expressions and WHY?
+
+> (ask Brian 'place)
+
+> (let ((where (ask Brian 'place)))
+       (ask where 'name))
+
+>  (ask Peoples-park 'appear bagel)
+
+
+
+2D.  The implication of all this is that there can be multiple names for
+objects.  One name is the value of the object's internal NAME variable. In
+addition, we can define a variable at the top-level to refer to an object.
+Moreover, one object can have a private name for another object.  For
+example, BRIAN has a variable PLACE which is currently bound to the object
+that represents People's Park.  Some examples to think about:
+
+      > (eq? (ask Telegraph-Ave 'look-in 'east) (ask Brian 'place))
+
+      > (eq? (ask Brian 'place) 'Peoples-Park)
+
+      > (eq? (ask (ask Brian 'place) 'name) 'Peoples-Park)
+
+
+OK.  Suppose we type the following into scheme:
+
+>  (define computer (instantiate thing 'Durer))
+
+
+Which of the following is correct?  Why?
+
+(ask 61a-lab 'appear computer)
+
+or
+
+(ask 61a-lab 'appear Durer)
+
+or 
+
+(ask 61a-lab 'appear 'Durer)
+
+What is returned by (computer 'name)?  Why?
+
+
+2E.  We have provided a definition of the THING class that does not use
+the object-oriented programming syntax described in the handout.  Translate
+it into the new notation.
+
+2F.  Sometimes it's inconvenient to debug an object interactively because
+its methods return objects and we want to see the names of the objects.  You
+can create auxiliary procedures for interactive use (as opposed to use
+inside object methods) that provide the desired information in printable
+form.  For example:
+
+(define (name obj) (ask obj 'name))
+(define (inventory obj)
+  (if (person? obj)
+      (map name (ask obj 'possessions))
+      (map name (ask obj 'things))))
+
+Write a procedure WHEREIS that takes a person as its argument and returns
+the name of the place where that person is.
+
+Write a procedure OWNER that takes a thing as its argument and returns the
+name of the person who owns it.  (Make sure it works for things that aren't
+owned by anyone.)
+
+Procedures like this can be very helpful in debugging the later parts of the
+project, so feel free to write more of them for your own use.
+
+
+Now it's time for you to make your first modifications to the adventure
+game.  This is where you split the work individually.
+
+PART I -- PERSON A:
+
+A3.  You will notice that whenever a person goes to a new place, the place
+gets an 'ENTER message.  In addition, the place the person previously
+inhabited gets an 'EXIT message.  When the place gets the message, it calls
+each procedure on its list of ENTRY-PROCEDURES or EXIT-PROCEDURES as
+appropriate.  Places have the following methods defined for manipulating
+these lists of procedures:  ADD-ENTRY-PROCEDURE, ADD-EXIT-PROCEDURE,
+REMOVE-ENTRY-PROCEDURE,
+REMOVE-EXIT-PROCEDURE, CLEAR-ALL-PROCS.  You can read their definitions in the
+code.
+
+Sproul Hall has a particularly obnoxious exit procedure attached to it.  Fix
+SPROUL-HALL-EXIT so that it counts how many times it gets called, and stops
+being obnoxious after the third time.
+
+Remember that the EXIT-PROCS list contains procedures, not names of
+procedures!  It's not good enough to redefine SPROUL-HALL-EXIT, since Sproul
+Hall's list of exit procedures still contains the old procedure.  The best
+thing to do is just to load adv-world.scm again, which will define a new
+sproul hall and add the new exit procedure.
+
+
+
+A4a.  We've provided people with the ability to say something using the
+messages 'TALK and 'SET-TALK.  As you may have noticed, some people around
+this campus start talking whenever anyone walks by.  We want to simulate this
+behavior.  In any such interaction there are two people involved: the one
+who was already at the place (hereafter called the TALKER) and the one who
+is just entering the place (the LISTENER).  We have already provided a
+mechanism so that the listener sends an ENTER message to the place when
+entering.  Also, each person is ready to accept a NOTICE message, meaning
+that the person should notice that someone new has come.  The talker should
+get a NOTICE message, and will then talk, because we've made a person's
+NOTICE method send itself a TALK message.  (Later we'll see that some special
+kinds of people have different NOTICE methods.)
+
+Your job is to modify the ENTER method for places, so that in addition to
+what that method already does, it sends a NOTICE message to each person in
+that place other than the person who is entering.  The NOTICE message should
+have the newly-entered person as an argument.  (You won't do anything with
+that argument now, but you'll need it later.)
+
+Test your implementation with the following:
+
+(define singer (instantiate person 'rick sproul-plaza))
+
+(ask singer 'set-talk "My funny valentine, sweet comic valentine")
+
+(define preacher (instantiate person 'preacher sproul-plaza))
+
+(ask preacher 'set-talk "Praise the Lord")
+
+(define street-person (instantiate person 'harry telegraph-ave))
+
+(ask street-person 'set-talk "Brother, can you spare a buck")
+
+YOU MUST INCLUDE A TRANSCRIPT IN WHICH YOUR CHARACTER WALKS AROUND AND
+TRIGGERS THESE MESSAGES.
+
+
+A4b.  So far the program assumes that anyone can go anywhere they want.
+In real life, many places have locked doors.
+
+Invent a MAY-ENTER? message for places that takes a person as an argument and
+always returns #T.  Then invent a LOCKED-PLACE class in which the MAY-ENTER?
+method returns #T if the place is unlocked, or #F if it's locked.  (It should
+initially be locked.)  The LOCKED-PLACE class must also have an UNLOCK
+message.  For simplicity, write this method with no arguments and have it
+always succeed.  In a real game, we would also invent keys, and a mechanism
+requiring that the person have the correct key in order to unlock the door.
+(That's why MAY-ENTER? takes the person as an argument.)
+
+Modify the person class so that it checks for permission to enter before
+moving from one place to another.  Then create a locked place and test
+it out.
+
+
+A5.  Walking around is great, but some people commute from far away, so
+they need to park their cars in garages.  A car is just a THING, but you'll
+have to invent a special kind of place called a GARAGE.  Garages have two
+methods (besides the ones all places have): PARK and UNPARK.  You'll also
+need a special kind of THING called a TICKET; what's special about it is
+that it has a NUMBER as an instantiation variable.
+
+The PARK method takes a car (a THING) as its argument.  First check to be sure
+that the car is actually in the garage.  (The person who possesses the car
+will enter the garage, then ask to park it, so the car should have entered the
+garage along with the person before the PARK message is sent.)  Then generate
+a TICKET with a unique serial number.  (The counter for serial numbers should
+be shared among all garages, so that we don't get in trouble later trying to
+UNPARK a car from one garage that was parked in a different garage.)  Every
+ticket should have the name TICKET.
+
+You'll associate the ticket number with the car in a key-value table like the
+one that we used with GET and PUT in 2.3.3.  However, GET and PUT refer to a
+single, fixed table for all operations; in this situation we need a separate
+table for every garage.  The file tables.scm contains an implementation of the
+table Abstract Data Type:
+
+constructor: (make-table) returns a new, empty table.
+
+mutator: (insert! key value table) adds a new key-value pair to a table.
+
+selector: (lookup key table) returns the corresponding value, or #F if
+				the key is not in the table.
+
+You'll learn how tables are implemented in 3.3.3 (pp. 266-268).
+For now, just take them as primitive.
+
+Make a table entry with the ticket number as the key, and the car as the
+value.  Then ask the car's owner to lose the car and take the ticket.
+
+The UNPARK method takes a ticket as argument.  First make sure the object
+you got is actually a ticket (by checking the name).  Then look up the
+ticket number in the garage's table.  If you find a car, ask the ticket's
+owner to lose the ticket and take the car.  Also, insert #F in the table for
+that ticket number, so that people can't unpark the car twice.
+
+A real-life garage would have a limited capacity, and would charge money
+for parking, but to simplify the project you don't have to simulate those
+aspects of garages.
+
+
+--- End of Part I for Person A
+
+
+PART I, PERSON B:
+
+
+B3.  Define a method TAKE-ALL for people.  If given that message, a person
+should TAKE all the things at the current location that are not already
+owned by someone.
+
+
+B4a.  It's unrealistic that anyone can take anything from anyone.  We want to
+give our characters a STRENGTH, and then one person can take something from
+another only if the first has greater STRENGTH than the second.
+
+However, we aren't going to clutter up the person class by adding a local
+STRENGTH variable.  That's because we can anticipate wanting to add lots
+more attributes as we develop the program further.  People can have CHARISMA
+or WISDOM; things can be FOOD or not; places can be INDOORS or not.
+Therefore, you will create a class called BASIC-OBJECT that keeps a local
+variable called PROPERTIES containing an attribute-value table like the
+one that we used with GET and PUT in 2.3.3.  However, GET and PUT refer to
+a single, fixed table for all operations; in this situation we need a
+separate table for every object.  The file tables.scm contains an
+implementation of the table Abstract Data Type:
+
+constructor: (make-table) returns a new, empty table.
+
+mutator: (insert! key value table) adds a new key-value pair to a table.
+
+selector: (lookup key table) returns the corresponding value, or #F if
+				the key is not in the table.
+
+You'll learn how tables are implemented in 3.3.3 (pp. 266-268).
+For now, just take them as primitive.
+
+You'll modify the person, place and thing classes so that they will inherit
+from basic-object.  This object will accept a message PUT so that
+	> (ask Brian 'put 'strength 100)
+does the right thing.  Also, the basic-object should treat any message not
+otherwise recognized as a request for the attribute of that name, so
+	> (ask Brian 'strength)
+	100
+should work WITHOUT having to write an explicit STRENGTH method in the
+class definition.
+
+Don't forget that the property list mechanism in 3.3.3 returns #F if you ask
+for a property that isn't in the list.  This means that
+	> (ask Brian 'charisma)
+should never give an error message, even if we haven't PUT that property in
+that object.  This is important for true-or-false properties, which will
+automatically be #F (but not an error) unless we explicitly PUT a #T
+value for them.
+
+Give people some reasonable (same for everyone) initial strength.  Next
+week they'll be able to get stronger by eating.
+
+B4b.  You'll notice that the type predicate PERSON? checks to see if the type
+of the argument is a member of the list '(person police thief).  This means
+that the PERSON? procedure has to keep a list of all the classes that
+inherit from PERSON, which is a pain if we make a new subclass.
+
+We'll take advantage of the property list to implement a better system for
+type checking.  If we add a method named PERSON? to the person class, and
+have it always return #T, then any object that's a type of person will
+automatically inherit this method.  Objects that don't inherit from person
+won't find a PERSON? method and won't find an entry for person? in their
+property table, so they'll return #F.
+
+Similarly, places should have a PLACE? method, and things a THING? method.
+
+Add these type methods and change the implementation of the type predicate
+procedures to this new implementation.
+
+
+B5.  In the modern era, many places allow you to get connected to the net.
+Define a HOTSPOT as a kind of place that allows network connectivity.  Each
+hotspot should have a PASSWORD (an instantiation variable) that you must know
+to connect.  (Note: We're envisioning a per-network password, not a per-person
+password as you use with AirBears.)  The hotspot has a CONNECT method with two
+arguments, a LAPTOP (a kind of thing, to be invented in a moment) and a
+password.  If the password is correct, and the laptop is in the hotspot, add
+it to a list of connected laptops.  When the laptop leaves the hotspot, remove
+it from the list.
+
+Hotspots also have a SURF method with two arguments, a laptop and a text
+string, such as
+
+		"http://www.cs.berkeley.edu"
+
+If the laptop is connected to the network, then the surf method should
+
+	(system (string-append "lynx " url))
+
+where URL is the text string argument.
+
+Now invent laptops.  A laptop is a thing that has two extra methods:  CONNECT,
+with a password as argument, sends a CONNECT message to the place where the
+laptop is.  SURF, with a URL text string as argument, sends a SURF message to
+the place where it is.  Thus, whenever a laptop enters a new hotspot, the user
+must ask to CONNECT to that hotspot's network; when the laptop leaves the
+hotspot, it must automatically be disconnected from the network.  (If it's in
+a place other than a hotspot, the SURF message won't be understood; if it's in
+a hotspot but not connected, the hotspot won't do anything.)
+
+
+--- End of Part I, PERSON B.
+
+
+PART II:
+
+This part of the project includes three exercises for each person, but YOU
+HAVE TO READ EACH OTHER'S CODE midweek, because one partner's exercises 7 and
+8 build on the other partner's exercise 6.  Finally, exercise 9 requires the
+two partners' work to be combined.  You will have to create a version of
+adv.scm that has both partners' changes.  This may take some thinking!  If
+both parners modify the same method in the same object class, you'll have to
+write a version of the method that incorporates both modifications.
+
+
+PART II, PERSON A:
+
+Adv.scm includes a definition of the class THIEF, a subclass of person.
+A thief is a character who tries to steal food from other people.  Of
+course, Berkeley can not tolerate this behavior for long.  Your job is to
+define a POLICE class; police objects catch thieves and send them directly
+to jail.  To do this you will need to understand how theives work.
+
+Since a thief is a kind of person, whenever another person enters the place
+where the thief is, the thief gets a NOTICE message from the place.  When
+the thief notices a new person, he does one of two things, depending on the
+state of his internal BEHAVIOR variable.  If this variable is set to STEAL,
+the thief looks around to see if there is any food at the place.  If there
+is food, the thief takes the food from its current possessor and sets his
+behavior to RUN.  When the thief's behavior is RUN, he moves to a new random
+place whenever he NOTICEs someone entering his current location.  The RUN
+behavior makes it hard to catch a thief.
+
+Notice that a thief object delegates many messages to its person object.
+
+
+A6a.  To help the police do their work, you will need to create a place called
+jail.  Jail has no exits.  Moreover, you will need to create a method for
+persons and thieves called GO-DIRECTLY-TO.  Go-directly-to does not require
+that the new-place be adjacent to the current-place.  So by calling (ASK
+THIEF 'GO-DIRECTLY-TO JAIL) the police can send the thief to jail no matter
+where the thief currently is located, assuming the variable thief is bound
+to the thief being apprehended.
+
+
+A6b.  Thieves sometimes try to leave their place in a randomly chosen
+direction.  This, it turns out, won't work if there are no exits from
+that place -- for example, the jail.  Modify the THIEF class so that
+a thief won't try to leave a place with no exits.
+
+** Now get your partner to explain problem B6 and its solution. **
+
+A7a.  We are now going to invent restaurant objects.  People will interact
+with the restaurants by buying food there.  First we have to make it possible
+for people to buy stuff.  Give PERSON objects a MONEY property, which is a
+number, saying how many dollars they have.  Note that money is not an
+object.  We implement it as a number because, unlike the case of objects
+such as chairs and potstickers, a person needs to be able to spend SOME
+money without giving up all of it.  In principle we could have objects like
+QUARTER and DOLLAR-BILL, but this would make the change-making process
+complicated for no good reason.
+
+To make life simple, we'll have every PERSON start out with $100.  (We should
+really start people with no money, and invent banks and jobs and so on, but
+we won't.)  Create two methods for people, GET-MONEY and PAY-MONEY, each of
+which takes a number as argument and updates the person's money value
+appropriately.  PAY-MONEY must return true or false depending on whether
+the person had enough money.
+
+
+A7b.  Another problem with the adventure game is that Noah's only has one
+bagel.  Once someone has taken that bagel, they're out of business.
+
+To fix this, we're going to invent a new kind of place, called a RESTAURANT.
+(That is, RESTAURANT is a subclass of PLACE.)  Each restaurant serves only
+one kind of food.  (This is a simplification, of course, and it's easy to see
+how we might extend the project to allow lists of kinds of food.)  When a
+restaurant is instantiated, it should have two extra arguments, besides the
+ones that all places have: the class of food objects that this restaurant
+sells,  and the price of one item of this type:
+
+   > (define-class (bagel) (parent (food ...)) ...)
+
+   > (define Noahs (instantiate restaurant 'Noahs bagel 0.50))
+
+Notice that the argument to the restaurant is a CLASS, not a particular
+bagel (instance).
+
+Restaurants should have two methods.  The MENU method returns a list
+containing the name and price of the food that the restaurant sells.
+The SELL method takes two arguments, the person who wants to buy something
+and the name of the food that the person wants.  The SELL method must first
+check that the restaurant actually sells the right kind of food.  If so,
+it should ASK the buyer to PAY-MONEY in the appropriate amount.  If that
+succeeds, the method should instantiate the food class and return the new
+food object.  The method should return #F if the person can't buy the food.
+
+
+A8.  Now we need a BUY method for people.  It should take as argument the
+name of the food we want to buy:  (ask Brian 'buy 'bagel).  The method must
+send a SELL message to the restaurant.  If this succeeds (that is, if the
+value returned from the SELL method is an object rather than #F) the new food
+should be added to the person's possessions.
+
+--- Person A skip to question 9 below.
+
+PART II, PERSON B:
+
+B6.  The way we're having people take food from restaurants is unrealistic
+in several ways.  Our overall goal this week is to fix that.  As a first
+step, you are going to create a FOOD class.
+We will give things that are food two properties, an EDIBLE? property
+and a CALORIES property.  EDIBLE?  will have the value #T if the object is a
+food.  If a PERSON eats some food, the food's CALORIES are added to the
+person's STRENGTH.
+
+(Remember that the EDIBLE? property will automatically be false for objects
+other than food, because of the way properties were implemented in question B4.
+You don't have to go around telling all the other stuff not to be edible
+explicitly.)
+
+Write a definition of the FOOD class that uses THING as the parent class.
+It should return #T when you send it an EDBILE? message, and it should
+correctly respond to a CALORIES message.
+
+Replace the procedure named EDIBLE? in the original adv.scm with a new
+version that takes advantage of the mechanism you've created, instead of
+relying on a built-in list of types of food.
+
+Now that you have the FOOD class, invent some child classes for particular
+kinds of food.  For example, make a bagel class that inherits from FOOD.
+Give the bagel class a class-variable called NAME whose value is the word
+bagel.  (We'll need this later when we invent RESTAURANT objects.)
+
+Make an EAT method for people.  Your EAT method should look at your
+possessions and filter for all the ones that are edible.  It should then add
+the calorie value of the foods to your strength.  Then it should make the
+foods disappear (no longer be your possessions and no longer be at your
+location).
+
+** Now get your partner to explain problem A6 and its solution. **
+
+B7.  Your job is to define the police class.  A policeperson is to have the
+following behavior:
+
+The police stays at one location.  When the police notices a new person
+entering the location, the police checks to see if that person is a thief.
+If the person is a thief the police says "Crime Does Not Pay," then takes
+away all the thief's possessions and sends the thief directly to jail.
+
+Give thieves and police default strengths.  Thieves should start out stronger
+than persons, but police should be stronger than thieves.  Of course, if you
+eat lots you should be able to build up enough STRENGTH (mass?) to take food
+away from a thief.  (Only a character with a lot of CHUTZPAH would take food
+away from the police. :-)
+
+Please test your code and turn in a transcript that shows the thief stealing
+your food, you chasing the thief and the police catching the thief.  In case
+you haven't noticed, we've put a thief in Sproul Plaza.
+
+
+B8.  Now we want to reorganize TAKE so that it looks to see who previously
+possesses the desired object.  If its possessor is 'NO-ONE, go ahead and
+take it as always.  Otherwise, invoke
+	(ask thing 'MAY-TAKE? receiver)
+The MAY-TAKE? method for a thing that belongs to someone should compare
+the strength of its owner with the strength of the requesting person to
+decide whether or not it can be taken.  The method should return #F
+if the person may not take the thing, or the thing itself if the person may
+take it.  This is a little more complicated than necessary right now, but
+we are planning ahead for a situation in which, for example, an object
+might want to make a clone of itself for a person to take.
+
+Note the flurry of message-passing going on here.  We send a message to the
+taker.  It sends a message to the thing, which sends messages to two people
+to find out their strengths.
+
+--- End of Part II, Person B (but both partners do question 8 below).
+
+9.  Combine the two partners' work.  For example, both partners have
+created new methods for the PERSON class.  Both partners have done work
+involving strengths of kinds of people; make sure they work together.
+
+Now make it so that when a POLICE person asks to BUY some food the
+restaurant doesn't charge him or her any money.  (This makes the game
+more realistic...)
+
+******** OPTIONAL **********
+As you can imagine, this is a truly open-ended project.  If you have the
+time and inclination, you can populate your world with new kinds of people
+(e.g., punk-rockers), places (Gilman-St), and especially things (magic
+wands, beer, gold pieces, cars looking for parking places...).
+
+For your enjoyment we have developed a procedure that creates a labyrinth (a
+maze) that you can explore.  To do so, load the file ~cs61a/lib/labyrinth.scm.
+[Note: labyrinth.scm may need some modification to work with the procedures
+you developed in part two of the project.]
+
+Legend has it that there is a vast series of rooms underneath Sproul Plaza.
+These rooms are littered with food of bygone days and quite a few theives.
+You can find the secret passage down in Sproul Plaza.
+
+You may want to modify FANCY-MOVE-LOOP so that you can look around in nearby
+rooms before entering so that you can avoid thieves.  You might also want
+your character to maintain a list of rooms visited on its property list so
+you can find your way back to the earth's surface.
diff --git a/js/games/nluqo.github.io/~bh/61a-pages/Volume1/Project3/obj.scm b/js/games/nluqo.github.io/~bh/61a-pages/Volume1/Project3/obj.scm
new file mode 100644
index 0000000..d4a9d7a
--- /dev/null
+++ b/js/games/nluqo.github.io/~bh/61a-pages/Volume1/Project3/obj.scm
@@ -0,0 +1,279 @@
+;;; obj.scm version 4.0 5/18/2000
+;;; -- implementation of the object-oriented syntax
+;; By Matt Wright, based on a handout from MIT
+;; Revised for STk by Brian Gaeke - removed scm and procedure->macro
+
+;;; Utilities
+
+;; MAKNAM: create a new symbol whose name is the concatenation of the 
+;; names of those in the symbol list SYMBOLS.
+(define (maknam . symbols)
+  (string->symbol (apply string-append (map symbol->string symbols))))
+
+;; ASK: send a message to an object
+
+; The dot in the first line of the definition of ASK, below, makes it
+; take a variable number of arguments.  The first argument is associated
+; with the formal parameter OBJECT; the second with MESSAGE; any extra
+; actual arguments are put in a list, and that list is associated with
+; the formal parameter ARGS.  (If there are only two actual args, then
+; ARGS will be the empty list.)
+
+; APPLY takes two arguments, a procedure and a list, and applies the
+; procedure to the things in the list, which are used as actual
+; argument values.
+
+(define (ask object message . args)
+  (let ((method (object message)))
+    (if (method? method)
+	(apply method args)
+	(error "No method " message " in class " (cadr method)))))
+
+(define (no-method name)
+  (list 'no-method name))
+
+(define (no-method? x)
+  (if (pair? x)
+      (eq? (car x) 'no-method)
+      #f))
+
+(define (method? x)
+  (not (no-method? x)))
+
+
+;; INSTANTIATE and INSTANTIATE-PARENT:  Create an instance of a class
+
+; The difference is that only INSTANTIATE initializes the new object
+
+(define (instantiate class . arguments)
+  (let ((new-instance (apply (class 'instantiate) arguments)))
+    (ask new-instance 'initialize new-instance)
+    new-instance))
+
+(define (instantiate-parent class . arguments)
+  (apply (class 'instantiate) arguments))
+
+;; GET-METHOD: Send a message to several objects and return the first
+;; method found (for multiple inheritance)
+
+(define (get-method give-up-name message . objects)
+  (if (null? objects)
+      (no-method give-up-name)
+      (let ((method ((car objects) message)))
+	(if (method? method)
+	    method
+	    (apply get-method (cons give-up-name
+				    (cons message (cdr objects)) ))))))
+
+
+
+;; USUAL: Invoke a parent's method
+;; Note: The 'send-usual-to-parent method is put in automatically by
+;; define-class.
+
+(define-macro (usual . args)
+	     `(ask dispatch 'send-usual-to-parent . ,args))
+
+
+;; DEFINE-CLASS:  Create a new class.
+
+; DEFINE-CLASS is a special form.  When you type (define-class body...)
+; it's as if you typed (make-definitions (quote body...)).  In other
+; words, the argument to DEFINE-CLASS isn't evaluated.  This makes sense
+; because the argument isn't Scheme syntax, but rather is the special
+; object-oriented programming language we're defining.
+; Make-definitions transforms the OOP notation into a standard Scheme
+; expression, then uses EVAL to evaluate the result.  (You'll see EVAL
+; again in chapter 4 with the metacircular evaluator.)
+
+; When you define a class named THING, for example, two global Scheme
+; variables are created.  The variable THING has as its value the
+; procedure that represents the class.  This procedure is invoked by
+; INSTANTIATE to create instances of the class.  A second variable,
+; THING-DEFINITION, has as its value the text of the Scheme expression
+; that defines THING.  This text is used only by SHOW-CLASS, the
+; procedure that lets you examine the result of the OOP-to-Scheme
+; translation process.
+
+(define-macro (define-class . body) (make-definitions body))
+
+(define (make-definitions form)
+  (let ((definition (translate form)))
+    (eval `(define ,(maknam (class-name form) '-definition) ',definition))
+    (eval definition)
+    (list 'quote (class-name form))))
+
+(define (show-class name)
+  (eval (maknam name '-definition)) )
+
+; TRANSLATE does all the work of DEFINE-CLASS.
+; The backquote operator (`) works just like regular quote (') except
+; that expressions proceeded by a comma are evaluated.  Also, expressions
+; proceeded by ",@" evaluate to lists; the lists are inserted into the
+; text without the outermost level of parentheses.
+
+(define (translate form)
+  (cond ((null? form) (error "Define-class: empty body"))
+	((not (null? (obj-filter form (lambda (x) (not (pair? x))))))
+	 (error "Each argument to define-class must be a list"))
+	((not (null? (extra-clauses form)))
+	 (error "Unrecognized clause in define-class:" (extra-clauses form)))
+	(else 
+	 `(define ,(class-name form)
+	    (let ,(class-var-bindings form)
+	      (lambda (class-message)
+		(cond
+		 ,@(class-variable-methods form)
+		 ((eq? class-message 'instantiate)
+		  (lambda ,(instantiation-vars form)
+		    (let ((self '())
+			  ,@(parent-let-list form)
+			  ,@(instance-vars-let-list form))
+		      (define (dispatch message)
+			(cond
+			 ,(init-clause form)
+			 ,(usual-clause form)
+			 ,@(method-clauses form)
+			 ,@(local-variable-methods form)
+			 ,(else-clause form) ))
+		      dispatch )))
+		 (else (error "Bad message to class" class-message)) )))))))
+
+(define *legal-clauses*
+  '(instance-vars class-vars method default-method parent initialize))
+
+(define (extra-clauses form)
+  (obj-filter (cdr form)
+	      (lambda (x) (null? (member (car x) *legal-clauses*)))))
+
+(define class-name caar)
+
+(define (class-var-bindings form)
+  (let ((classvar-clause (find-a-clause 'class-vars form)))
+    (if (null? classvar-clause)
+	'()
+	(cdr classvar-clause) )))
+
+(define instantiation-vars cdar)
+
+(define (parent-let-list form)
+  (let ((parent-clause (find-a-clause 'parent form)))
+    (if (null? parent-clause)
+	'()
+	(map (lambda (parent-and-args)
+	       (list (maknam 'my- (car parent-and-args))
+		     (cons 'instantiate-parent parent-and-args)))
+	     (cdr parent-clause)))))
+
+(define (instance-vars-let-list form)
+  (let ((instance-vars-clause (find-a-clause 'instance-vars form)))
+    (if (null? instance-vars-clause)
+	'()
+	(cdr instance-vars-clause))))
+
+(define (init-clause form)
+  (define (parent-initialization form)
+    (let ((parent-clause (find-a-clause 'parent form)))
+      (if (null? parent-clause)
+	  '()
+	  (map
+	   (lambda (parent-and-args)
+	     `(ask ,(maknam 'my- (car parent-and-args)) 'initialize self) )
+	   (cdr parent-clause) ))))
+  (define (my-initialization form)
+    (let ((init-clause (find-a-clause 'initialize form)))
+      (if (null? init-clause) '()
+	  (cdr init-clause))))
+  (define (init-body form)
+    (append (parent-initialization form)
+	    (my-initialization form) ))
+
+  `((eq? message 'initialize)
+    (lambda (value-for-self)
+      (set! self value-for-self)
+      ,@(init-body form) )))
+
+(define (variable-list var-type form)
+  (let ((clause (find-a-clause var-type form)))
+    (if (null? clause)
+	'()
+	(map car (cdr clause)) )))
+
+(define (class-variable-methods form)
+  (cons `((eq? class-message 'class-name) (lambda () ',(class-name form)))
+	(map (lambda (variable)
+	       `((eq? class-message ',variable) (lambda () ,variable)))
+	     (variable-list 'class-vars form))))
+
+(define (local-variable-methods form)
+  (cons `((eq? message 'class-name) (lambda () ',(class-name form)))
+	(map (lambda (variable)
+	       `((eq? message ',variable) (lambda () ,variable)))
+	     (append (cdr (car form))
+		     (variable-list 'instance-vars form)
+		     (variable-list 'class-vars form)))))
+
+(define (method-clauses form)
+  (map
+   (lambda (method-defn)
+     (let ((this-message (car (cadr method-defn)))
+	   (args (cdr (cadr method-defn)))
+	   (body (cddr method-defn)))
+       `((eq? message ',this-message)
+	 (lambda ,args ,@body))))
+   (obj-filter (cdr form) (lambda (x) (eq? (car x) 'method))) ))
+
+(define (parent-list form)
+  (let ((parent-clause (find-a-clause 'parent form)))
+    (if (null? parent-clause)
+	'()
+	(map (lambda (class) (maknam 'my- class))
+	     (map car (cdr parent-clause))))))
+
+(define (usual-clause form)
+  (let ((parent-clause (find-a-clause 'parent form)))
+    (if (null? parent-clause)
+	`((eq? message 'send-usual-to-parent)
+	  (error "Can't use USUAL without a parent." ',(class-name form)))
+	`((eq? message 'send-usual-to-parent)
+	  (lambda (message . args)
+	    (let ((method (get-method ',(class-name form)
+				      message
+				      ,@(parent-list form))))
+	      (if (method? method)
+		  (apply method args)
+		  (error "No USUAL method" message ',(class-name form)) )))))))
+
+(define (else-clause form)
+  (let ((parent-clause (find-a-clause 'parent form))
+	(default-method (find-a-clause 'default-method form)))
+    (cond
+     ((and (null? parent-clause) (null? default-method))
+      `(else (no-method ',(class-name form))))
+     ((null? parent-clause)
+      `(else (lambda args ,@(cdr default-method))))
+     ((null? default-method)
+      `(else (get-method ',(class-name form) message ,@(parent-list form))) )
+     (else
+      `(else (let ((method (get-method ',(class-name form)
+				       message
+				       ,@(parent-list form))))
+	       (if (method? method)
+		   method
+		   (lambda args ,@(cdr default-method)) )))))))
+
+(define (find-a-clause clause-name form)
+  (let ((clauses (obj-filter (cdr form)
+			     (lambda (x) (eq? (car x) clause-name)))))
+    (cond ((null? clauses) '())
+	  ((null? (cdr clauses)) (car clauses))
+	  (else (error "Error in define-class: too many "
+		       clause-name "clauses.")) )))
+
+(define (obj-filter l pred)
+  (cond ((null? l) '())
+	((pred (car l))
+	 (cons (car l) (obj-filter (cdr l) pred)))
+	(else (obj-filter (cdr l) pred))))
+
+(provide "obj")
diff --git a/js/games/nluqo.github.io/~bh/61a-pages/Volume1/Project3/small-world.scm b/js/games/nluqo.github.io/~bh/61a-pages/Volume1/Project3/small-world.scm
new file mode 100644
index 0000000..dcd6bd1
--- /dev/null
+++ b/js/games/nluqo.github.io/~bh/61a-pages/Volume1/Project3/small-world.scm
@@ -0,0 +1,28 @@
+;;; small-world.scm
+;;; Miniature game world for debugging the CS61A adventure game project.
+;;; You can load this instead of adv-world.scm, and reload it quickly
+;;; whenever you change a class.
+
+;;; How to use this file:
+;;; If, for example, your person class doesn't work, and you do something
+;;; like (define Matt (instantiate person 'Matt)), and then fix your
+;;; person class definition, Matt is still bound to the faulty person
+;;; object from before.  However, reloading this file whenever you
+;;; change something should redefine everything in your world with the
+;;; currently loaded (i.e. most recent) versions of your classes.
+
+(define 61A-Lab (instantiate place '61A-Lab))
+(define Lounge (instantiate place 'Lounge))
+(can-go 61A-Lab 'up Lounge)
+(can-go Lounge 'down 61A-Lab)
+;;;  Hopefully you'll see more of the world than this in real life
+;;;  while you're doing the project!
+
+(define homework-box (instantiate thing 'homework-box))
+(ask 61A-Lab 'appear homework-box)
+
+(define Coke (instantiate thing 'Coke))
+(ask Lounge 'appear Coke)
+
+(define laba (instantiate person 'Lab-assistant 61A-Lab))
+