View this PageEdit this PageAttachments to this PageHistory of this PageHomeRecent ChangesSearch the SwikiHelp Guide
Hotspots: Admin Pages | Turn-in Site |
Current Links: Cases Final Project Summer 2007

Questions on Fall2001 P4 Milestone

Ask about indirect objects, containment, layering, extensible language here:

when is it due?
Oct 18 – see Fall 2001 Project Milestones Mark Guzdial

What may we assume about the browser being used to test Milestone 4?
May we safely assume that the browser will support tables?
It[tables] would allow some pretty neat user interface designs.

Squeaky Clean Squeakers
Let's say Netscape 4 as the target browser. Mark Guzdial

When performing an indirectVerb on an AGObject, does the AGObject HAVE to be in the AGPlayer's inventory? ie can a player just walk into a room and see a knife sitting on the ground and put it on the table without taking it first. In the example that you gave you only showed an AGPlayer performing an indirect verb on an item already in his inventory.

Squeaky Clean Squeakers
Yes, for now, let's retain the same semantics: You can't manipulate an object unless it is first taken. Mark Guzdial

What Platform will P4 be tested on? Are there any methods that allow us to set the server directory from within the code, as opposed to setting it through the source browser?

Team Echo Rising
You may not assume an OS for P4. You could always compile the method yourself – why do you want to control that? Mark Guzdial

Right now I am just messing around with the web browser and I am just trying to print out the name of the AGWorld I am linking it too, but it keeps printing out 'nil'. I checked the method where I set the world inside of my interface and it sets it correctly there.
Try putting it to the Transcript. My bet is that it's nil there, too. Or put self halt in your code to bring up the debugger and check the value. Mark Guzdial

When a surface is told to accept: an object, an event is generated that can be caught by when:do:.
Does the above imply that AGObjects must understand when:do:? If so, we probably want it to understand flag: value: as well..which means AGObjects might as well be a kind of AGCharacter. A special kind that can have stuff on it and in it.
Is an Object a kind of Character? Or is a character a kind of object? Mark Guzdial

The surface can test whether it's being sent: an object.
Which is really bad design. Why not ask the thing if it can be put on a surface, and catch that message reasonably? Mark Guzdial

does this mean you can't put characters or players inside or on containers or surfaces respectively? What about the Troll jumping out of the wooden box to tear the player to bits?
What is the "this" you're referring to? Why can't you put characters or players inside containers or surfaces? I don't see why not. Mark Guzdial
He is referring to the specification that you called bad design. The surface can test whether it's being sent an object. this being the fact that a surface should be able to test whether it is being sent an object. So does the fact that you said it was bad design mean we don't have to implement it 8) Holland King
There's actually a big discussion in the Squeak list right now about this. In general, it's considered bad form to say "input isKindOf: AGObject". It's better form to ask "input canBeOnSurface" where the method "canBeOnSurface" is polymorphic: For AGObject, return true. For everything else (e.g., put it in Object), return false. Mark Guzdial

It can then take some action before accepting the object on: itself.

is this action you speak of the do block of the when do?

Terribly confused
Errol Summerlin
What is "this" action? Mark Guzdial

In the example you give, if you make the indirect object a surface and a container, how is it supposed to know which one it should be? In your example if you make another indirect verb to put the knife in the table, the table's when block will still evaluate to true and put it on the table. Should we assume then that you can't have a container and a surface together on one object?
Squeaky Clean Squeakers
My strong suggestion is to disallow objects being BOTH a surface and a container. Yes, there is a Box with a lid on it in the real world. Don't bother with trying to make that work in this world, at least not for now. Put it on the list of things to fix in P6. Mark Guzdial
Yes, there is a box with a lid in the real world, but..BUT! the lidded box is topologically equivalent to a box with no lid! SO, if you have your lidded box, by a series of constant deformations, you can change its' shape to that of an unlidded box or even a plate, and then this really isn't even an issue anymore! Right? Right! Of course, applying that idea to your project could yield some very bizarre results.... Shaggz

Is it essential to have a Submit button on the web UI because pressing the enter key in the input box does the same thing.
That's only true if you have only one input box. No, you don't need a Submit button if it works as Enter in the text box. Mark Guzdial

Just wondering... is it possible to change the state of the game simultaneously through the Terminal UI, and the web UI?
Of course one can! It's not required for P4, though. Feel free to add it as improved functionality in P6! Mark Guzdial

In the text of Milestone 4 you have "A surface understands on:" but in your sample code the (world object: knife) is actually being sent "on:". Is this a typo?
Also, in knife's indirectVerbMatch block it says "table accept: me", should this be "(world object: 'table') accept: me"?
Drop removes an object from a container, but there is no method that removes an object from a surface.

Squeaky Clean Squeakers
Thanks, Squeaky Clean Squeakers – I've fixed all three. Mark Guzdial

When you look at on object that contains something, can you see its contents? IE can you see a marble in a bag when you enter a room? If not, how do you see its contents.

Squeaky Clean Squeakers
I think that when you look at the object, you should see its contents. Mark Guzdial

Excatly how is the doVerb: used in object? I was looking at it and there was no examples about it. Does it evaluate a block or something (in which you pass in player, me, world) and for what purpose/context is it going to be used in?
There's an example when "examine" is defined. Note that doVerb: doesn't explicitly hand in the World, but the World is needed for the verb handler blocks, so the verbs/objects must know the World somehow – a bad coupling in the design that should probably be fixed in P6. Mark Guzdial

From the example code:
knife on: table.
kitchen to: #north attach: livingRoom.
kitchen contain: knife.
kitchen contain: kitten.
kitchen contain: table. "And indirectly, the knife"
Doesn't sending kitchen the contain: knife message remove the knife from it's current container (or surface) and place it "on the floor" or the kitchen? Or, should we allow an object to have both a container (the room) and be on a surface (the table). Personally it makes more sense to me for the knife to only be on the surface of the table which is contained by the room.
Everything from Nothing
I disagree – the knife is in the room and on the table, containment and layering. Layering is not equal to containment. Mark Guzdial
But these are two types of containment. The room directly contains the table. But the room only indirectly contains the actual knife. I know that sounds confusing so let me explain. In the example the room is called to explicitly contain both objects. However when you look at the room it's not supposed to print out that the room contains the knife except with relaationship to the table. I don't think it's room's job to create this description(it's tables). So there are two types of containment, one where the room will print a description and one where it will not. Unforunately this requires some vicious hacks to get working. Jared Parsons

Should we add the ablility to place objects in containers and on surfaces as part of the default vocabulary of the game, or should we assume that the workspace code will take care of doing that with indirectVerbMatch?
Everything from Nothing
Everything should be handled by default. Mark Guzdial

When we hit the refresh button on the browser should it do nothing?For us the last command is brought in and performed again. Is this an error in our code or just the way the web browser works?
Undefined. It certainly shouldn't generate an error. Mark Guzdial

Our input was "go east" and then we hit the refresh button and this is what happens:
Welcome to the The Household World
You are in: A bright and cheery kitchen, with daisies on the wallpaper and sunlight streaming through the window.
You see:
A dangerous knife
An adorable kitten.

There is an exit to the North
(input: go east)
Ouch!, you bumped into a wall
(hit refresh)
Ouch!, you bumped into a wall
(hit refresh)
Ouch!, you bumped into a wall
(hit refresh)
Ouch!, you bumped into a wall

Sounds like something that you shouldn't let happen... Mark Guzdial

If the player hits the close(x) button without typing "quit" in the command-line input, should that be the same as quitting the game, or must he explicitly type "quit"?
You can't tell. If the browser closes or if the person just goes away, you don't know. You could implement a timer to time out after, say, 30 minutes of inactivity. (It's not a requirement to do so, but it's something you can think about for P6.) Mark Guzdial

Question about the workspace code

table when: [:player :me :world | me sent: (world object: 'knife')] "Handle the accept"
do: [:player :me :world| player drop: (world object: 'knife').
(world object: 'knife') on: me.].

Why is player necessarily dropping the knife. For example. Take the workspace code when you first walk in the room. The player could issue the following command

>put the knife on the table

That should be a valid command but the container of the knife will be the kitchen at that point. The line would seem to be more robust if it were along the lines of
((world object: 'knife') container) drop: (world object: 'knife').
That would take care of both cases
Jared Parsons
Well, to put the knife on the table it has to be in your player's inventory since the current specs say that actions (other than look and take) only work on items in the player's inventory. Everything from Nothing
Yup – you can't put anything that isn't in your inventory. You can always make things more robust in P6. Mark Guzdial

Question on the containment... how are we suppose to go about putting this into the vocabulary because I dont see where you test this in your workspace code?
Also... should objects also have a method in: since we define a method called on: for layering.
Tim Hardcastle
"Put X into Y" is the form you have to support. No, it's not in the example code. Yes, building a method in: sounds like a good idea, but not required. Mark Guzdial

1.  Define the following javascript somewhere in your html page:

<script language="JavaScript">
  function setFocus( poForm ) {
    if( poForm.elements[0]!=null) {
      var i;
      var max = poForm.length;
      for( i = 0; i < max; i++ ) {
        if( poForm.elements[ i ].type != "hidden" &
          !poForm.elements[ i ].disabled &
          !poForm.elements[ i ].readOnly ) {
            poForm.elements[ i ].focus();

2.  Define your body tag as follows:  
(Note:  this assumes you only have one form on your page.)
<body onload="setFocus(document.forms[0]);">

3.  Enjoy!

I did find a javascript command to scroll down to an anchor, but since I only have one input box that I places at the bottom of the page, the setFocus() function effectively scrolled down for me.

I hope this helps someone,
Jonathan D'Andries

Ok this seems silly as it now stands an Object does everything a character can do, but it has extra functionality, but earlier you seemed to imply that character should be a subclass of object, when codewise, it seems the other way around. Since AGObjects now need when:do: blocks, the only difference is that objects can contain stuff and can toggle their takability. So I don't see why we can't make AGObject a subclass of AGCharacter. Though it doesn't make sense with the names the way they are, and AGObject isa AGCharacter with added functionality to toggle takeability..etc.
Sounds like you need something that sits above both AGObject and AGCharacter to factor out common functionality and data... Mark Guzdial

Question regarding factorial example in the book and the slides:

I tried testing this example for PWS

Mark had to hack the above to make save to this page work. Mark Guzdial

Number to compute:input type=text name="number"
value="Unknown function: request" size=10 maxlength=10>

However I get this error when trying to accept the code
"ifTrue: [request fields at: 'number Nothing more expected->' ifAbsent: ['0']]"

Why? and how do I fix it?
Jennifer Roper

Are you using 2.8 or 3.1? Make sure that those are real quotes, not something that PowerPoint inserted for you. Check that Dictionary understands at:ifAbsent: in your image. Mark Guzdial

Same problem here. Also, are there other sources on this programming the PWS, b/c I'm having a little trouble on w/ the examples on p.246-249.
Some specific questions, please? Mark Guzdial
Well, this is old and out-dated, but then again, so is PWS. Enjoy! Shaggz
Actually, I just saw the Cincom Smalltalk demo of their latest and greatest SSP (Smalltalk Server Pages) and they looked remarkably like PWS's... Mark Guzdial

processEvents question...In order to execute the do: block from the when dos, our object or character needs to somehow know what world he is in, but it does not make sense to me to have a character or object know what world it is in. It would really only know its container whether it be a room or an AGObject and what it contains. I suppose a room might know its world, but I really just don't understand why a room should be processing events inside of it anyway...It seems more logical to have a GameController of some sort that checks the when dos that know what world it is controlling and what interface it is getting input from. It should control making those changes to the world. It upsets me greatly that we are not allowed such freedoms in our design because of the messages which certain objects are required to understand.
Errol Summerlin
I'm glad you're upset, Errol! THAT'S THE POINT OF P6! Yes, the design I give you should start breaking down as we get to P4 and P5. That's what gives you the impetus to try to fix it in P6! Then in P7, you have to test your OWN design and see how well it works. Bottomline: DESIGN IS HARD! I give you one, you live in it, then you give yourself one and you live in it! To answer your question, though: Yes, you'll probably have to make some yucky connections. I don't like the GameController idea, though. I'd rather have the Parser inform the room that a turn has occurred, so the room can tell its objects that they can check their WhenDos – or something like that. Mark Guzdial

Use concatentation and "$' asString" to put the single quote character within your strings. Otherwise it thinks that you are trying to close out the string.
Ron Jeremy's Minions

Excatly how is the when: do: block for the kitten run...That is, for the knife, the player actually put it on the table but for the kitten, there is no indirect verbMatch or for the table to accept it. What I am saying is that I dont see how the table can be sent the kitten when there was no place that operation was performed.
The only way we see this happening is if you actually type:
table accept: kitten
on the workspace since there was no code that did this. Thanks
The way I understand it, sent: anObject should return a boolean that says whether "the last object it was sent" = anObject. the accept: theObject message apparently tells the object what "the last object it was sent". Accept does not put the anything anywhere...all it does is inform self that it has recieved an Object and to deal with it when it checks when: do: blocks. Hope that makes sense and someone please correct if I am totally off base.

I'm confused by the question, but the answer (who ever posted it) seems right to me. "on:" doesn't send "accept:" – it just makes the object go on. But if I "put X on Y" then the indirectVerbMatch:and:do: gets called. The surface Y is "sent:" the object X, and the surface Y can handle whether or not to "accept:" it. Mark Guzdial

Also, when should the when: do: blocks for objects be evaluated? Should it be after every event of the player/user because if thats the case, if you put the knife on the table and then take the knife. The when: do: block of table makes you drop it back on the table. Thanks

As I understand it the when dos are executed after the action taken by the player. Thus after the player inputs the command to put the knife on the table then the block associated with that verb is executed. Then the when do blocks are executed (allowing table the chance to accept the knife). After the when dos the player enters 'the next turn' and can pick up the knife normally. On a side note, should the player have to take the knife off the table before picking it up? Everything from Nothing
The Player should be able to simply "take knife" and it should come off the table. The description of the when:do: above from Everything from Nothing looks pretty good to me. Mark Guzdial

Someone deleted this here it is again...what exactly processEvents supposed to do? Can someone please give more decsription than that is given in the project 4 nfo file. Bharti Agarwal
processEvents is suppose to check all the when blocks, and if true execute the coresponding do block. Note: according to the specs from previous milestones it appears that we only automaticly check the when dos that objects and characters in the same room as the player after the player's input. Hope that made sense. :) Everything from Nothing
It might be nice to execute ALL the when blocks, even ones for things not in the same room. That way you could have an angry troll chase the player from room to room, wielding a razor sharp scrod all the while. Not really required, but neat. Shaggz
I agree with both Shaggz and Everything from NothingMark Guzdial

In ordered to implement the following line of code object must have an instance method called doVerb: verbString
houseWorld addRule: 'examine #object' do: [:dictionary :player :world |
(world object: (dictionary at: 'object')) doVerb: 'look'].

What verbs are possible to be passed by doVerb? I only ask because if use, or any verb which is equal in action to use, is called, to implement this the object must know about the player and the world to be able to execute is block with value:value:value: This would be bad design. Should we implement the bad design or should we assume that the verbs would be restricted to look or drop or "simple" verbs with a block to be performed.
Robert Schierholz
Yes, any verb, including 'use'. Yes, currently, that requires world and player knowledge. Another thing for the "Fix in P6" list. Mark Guzdial

Would the person using this I.P. ( as an ftp server for your squeak material please rectify your error. You apparently saved your image on the S: Jefferson server in the states cluster. Now, when I get squeak off the Jefferson server, it has your image on it, and I don't have write access to it either, so I can't fileIn my change files. Apparently, no one that gets squeak off of Jefferson can use it effectively. Please be more careful where you save your image from now on. Errol Summerlin

The corrupt images have been replaced with fresh ones and permissions are now set correctly. Yeah. Shaggz

Yes, there are two kinds of containment here. The Room contains the Knife, but the Room isn't supposed to be handling the description of the knife. If we had a Box explicitly declared to be a Container and it contained the knife, the Box's description should include the fact that the knife is in there. So, there is implicit containment (Room) and explicit containment (Box) and you have to deal with them separately...Another good P6 fixer-upper. Mark Guzdial

It was posted earlier that a player must hold an object for a direct action to be performed on it. Player need to also be able to access objects they indirectly contain.

For example add this to the workspace code:
jar := AGObject named: 'jar'.
jar description: 'A jar'.
jar longDescription: 'a clay jar'.
jar makeContainer
kitchen contain: jar.

Then you can perform the following series of commands
>take knife
>put knife in jar
>take jar
>take knife from jar

In this last command knife is the object and jar is the indirect object. Player does not contain the knife but this should be a perfectly valid command(otherwise you can't ever get an object from another object). So players need access to objects they indirectly contain also. Jared Parsons
I agree, Jared. Is there something we've said that makes this not work? Mark Guzdial

I think I see the question, Jared. Players need to be able to hold things they PUT. Of course, they're never holding things they TAKE. Mark Guzdial

In the M4 specifications – pickUp: and contain: are synonyms.

I dont understand how this is possible. Here is what I understand:

Now for the question: Do contain: and pickUp: have to check the item-to-be-picked's container before proceeding to contain it? If not, then the player would be able to pickUp: a Knife that is in a different room from him.

Absolut Squeak
Very well said – I've updated the specs accordingly. Mark Guzdial

Is there any way that we can get all of the html, or at least the body content, from the PWS reply in process:?
Absolut Squeak
No, because the HTTP request doesn't contain the HTML of the page that the user is using. (This makes sense: Why do you want to send back to the server that which it just sent you?) Suggestion: Dump to the Transcript the request fields and see all the information that is there, then backtrace. Mark Guzdial

I just seem to be having some problem with the layering. So if user says 'put kitten on table'.. Should 'the world' print 'Kitten jumped off the table' even if we DO NOT have a indirectVerbMatch for the object kitten.
Yes – some kind of default behavior is required. Mark Guzdial

When updating my web interface, I keep getting the message:

HTTP/1.0 400 Bad Request – only integers should be used as indices

I'm guessing this has something to do with using the:
request fields at: 'command' "command is the name of the text field where commands are entered"

So if I already have the page open (since I've been hackin' for a while), I can submit and see my input, I'm simply printing it to web page for now, instead of sending it to be processed, but if I try to go to a new page, it gives this message. So I tried saying:
('command' isNil) ifFalse: [request fields at: 'command']

Am I on the right track, or is it something else giving that error?
Charles Brian Quinn
Here's an easy way to debug this kind of thing. Dump out all of request fields printString onto the page and see what's there. Your code won't work: 'command' is never nil. There is a message at:ifAbsent:, e.g., request fields at: 'command' ifAbsent: ["Do something reasonable here"]. BUT...this wouldn't case this error. You're indexing something that isn't indexable. Put in a self halt and check your variables. Mark Guzdial

FYI: The sample code for containment has a typo on the line:
gadget := AGObject name: 'gadget'.
name: should be named:
Hope that helps... ps, thanks for posting the code !.

Git yo' Squeak on!
Fixed! Thanks! Mark Guzdial

good job Git yo' Squeak on! we were about to post the same observation


good job MotherSqueakers! we were about to post the observation that Git yo' Squeak on! posted the observation that we observed

Everything from Nothing

There are a few ambiguities about containment and such for this project:

1) According to the example code, table is reacting to when the user tries to "put the kitten on the table". But there is no verbmatch added to the AGObject kitten in the sample code.
table when: [:player :me :world | me sent: (world object: 'kitten')] "Reject the accept"
	do: [:player :me :world| player drop: (world object: 'kitten'). "Note: If kitten dropped, who should own it?  The room."
		world print: 'Kitten jumped off the table.'].

So when we add the indirect verb match to knife, how is kitten supposed to know about it as well?
The indirect verb match on knife is basically doing the default behavior. The kitten should still work. Mark Guzdial

2) Should 'put into', 'put on' be recognizable by all objects? ie, should we be able to put any object on top of/into any surface or container?

Yes, if the indirect object is a surface or container. Always provide reasonable default behavior. Mark Guzdial

3) In the sample gameplay, the game responds to putting the knife on the table, as in:
>put the knife on the table
The knife is on the table.

Are we expected to hardcode messages for putting AGObjects in/on and removing from containers and surfaces?

"hardcode messages"? Messages are required. You decide if you want them hardcoded or generated. Mark Guzdial

4) Does AGObject's makeContainer do anything more than simply set a flag that allows it to contain things?
Your call. Is it a flag setting? Or do you generate a new object and rebind the object's name? Mark Guzdial

5) When an AGObject is a surface, should it automatically accept items if not specifically added?
Sounds like reasonable default behavior... Mark Guzdial

The Goods

Suppose a class extends a class native to squeak 3.0 (i.e. OrderedCollection subclass: #AlphabeticallyOrderedCollection). Do we need to diagram the native class in our uml(i.e. OrderedCollection)?
man fockkk this stupid shit......
hey the code is too hard to decifer for another application you called me me again.....The homies came through with the supporting software......Dont worry...consider it done ;)....
hey if you really want a program as serious as that I wont part with it, without me....we can work out a deal....
I dont write for free....especially when it comes to that......

Link to this Page