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.
> (ask someperson 'take-all)
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 Lesson 6. 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:
(make-table) returns a new, empty table.(insert! key value table) adds a new key-value pair to a table.(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 SICP 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 the following call does the right thing:
    > (ask Brian 'put 'strength 100)
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 returns #f if you ask for a property that isn't in the list. This means that the following call should never give an error message, even if we haven't put that property in that object:
    > (ask Brian 'charisma)
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 initial strength. (They should be the same for every newly instantiated person object.) Later, they'll be able to get stronger by eating.
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.
> (ask brian 'person?)
 #t
Add these type methods and change the implementation of the type predicate
procedures (at the very bottom of adv.scm) to this new implementation. Don't
forget to add the definition for place?.
The new type predicate should do the following:
 > (person? brian)
 #t
 > (place? soda)
 #t
 > (thing? coffee)
 #t
Remember that person? should work for classes that inherit from person,
like thief and police (defined later). Similarly with place? and thing?
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 name and a password as instantiation variables that you must
know to connect.
> (define library (instantiate hotspot 'library 1234))   
;name of hotspot is library, password is 1234
(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 otherwise, return an error. When the laptop leaves the
hotspot, remove it from the list.
> (ask library 'connect somelaptop 1234)
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 (note the space after x in "lynx "). Otherwise, return an error.
> (ask library 'surf somelaptop "http://www.cs.berkeley.edu")
Now invent the laptop class. A laptop has one instantiation variable, its
name.
> (define somelaptop (instantiate laptop 'somelaptop)
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. If the
password is wrong, return an error.
> (ask somelaptop 'connect 1234)
A laptop also has another method, 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,
return an error).
> (ask somelaptop 'surf "www.berkeley.edu")