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 P2 Milestone

Ask about the adventure game here.

I don't think the percentages on the grading scale add up correctly. -Brandon Yarbrough

Email me if you need a group member.

Yes, you were right. Now fixed. Mark Guzdial

Does the TelnetMachine have a sort of a UI or display? Jesse Shieh

Yes. Try it. Mark Guzdial

If no one in the group implement part of P1 say the block part, I am assuming one person in the group is going to have to finish it. In other words there is no release of the entire working code. Just checking thanks,

Robert Schierholz

We're never going to go back and ask you to get P1 working again. If you can do without blocks, you don't have to implement it. Mark Guzdial

Two questions about P2:

1. What exactly does "die" do? The only thing we could think of was it stops the when: do: of that particular character. so then destroy is when it is actually removed from the room?

2. How many actions are there per object? I guess could you define multiple actions for each object (not just an alias). so could "use knife" and "throw knife" do different things? or is there one "use" action for every object and then you can simply alias it?

Thanks! Valeri Pyne

If something is dead, then it shows up in descriptions as dead, and it can't do anything. Destroy actually removes it from the room, as you say. You can have any number of actions for an object. You must implement the ones specified. Mark Guzdial

When we turnin code to the swiki, does each group member need to

turn-in code or is just a single submission from a group member

going to be sufficient? I did not see anything specifying this on the P2 turnin information page.

Kevin Wong

I think that the way we'll do it is that, for P2, just one person from the group turns it in. Once we know who is in which groups, we'll define group pages. Mark Guzdial

A question about AGRoom; when we create paths from room to room are we supposed to create paths back and forth? For example, the kitchen's north is the living room. Should we automagically make living room's south as the kitchen? Or should we not do this as the workspace code indicates? ("Create a door from the kitchen to the livingRoom. Note that there isn't automatically a door formed back.") Just making sure, thanks! Alfred Park

As the workspace code says. Doors aren't automagically made in both directions. There can be doors that, once you walk through them, there isn't a way back. Mark Guzdial

A lot of the project description doesn't seem to make any sesnse.

(sarcasm on)Of course! My goal is not to make sense and confuse you!(sarcasm off) We don't have an implementation to test the workspace code against, so I'm sure that there are errors. Please ask, and I'll be glad to fix it best I can. Mark Guzdial

First lets go with the AGObject's container property. The code for verbMatch: do: on knife shows that the object queries the container for characters. This doesn't make any sense. The player has picked up the knife so wouldn't the container be the player? If tis' not then does the container on every object change to the room that you're currently in if a player is holding it?

You're right. Fixed. Thanks. Mark Guzdial

Secondly. Why does the world print out to the user? That seems like a very poor design. For example by forcing the world to print out to the user ( as in knife verbMatch: do:) you have now limited the game to a signle player because the world would have no idea which player it should print to if there were more than one. It seems like it would make more sense for print to take multiple fields. so that you could indicate the player for which to print. Jared Parsons

Like I said in class, this is single person, on purpose, to make it simpler. Make the design better in P6 – that's the point. Mark Guzdial

Few questions.

1. Will there be any need to implement input that doesn't match a verb? For example, it seems like the current setup only works with simple commands on AGObjects, 'take knife' 'use knife' 'look room' etc. What about something like 'what time is it' ie, something that doesn't use a "variable" like in milestone1, or 'talk ogre' something that corresponds to an AGCharacter not AGObject?

For right now, you only need to implement the language forms we're specifying. Mark Guzdial

2. For the "Simple Vocabulary" that we are supposed to implement. Do you want us to hardcode this? I mean, it seems like just by adding a 'use' statement to a knife but not adding it to a paper, we are saying one can use a knife but not the paper. By adding 'take' to a knife but not to a stove we are saying one can take the knife but not the paper.

You probably shouldn't be hard codeing anything. Think of what "take knife" really is. It's a verb followed by an object You can construct rules based on this so that you only have to have one or two rules for every object in the game. The AGObjects themselves should be responsible for dealing with these verbs Jared Parsons

Jared is partially right. You should be implementing as flexibly as possible. But yes, you must have defined the core vocabulary from the beginning, along with the conditions that make sense. For example, you shouldn't be able to 'use' anything that you don't have in your inventory. Mark Guzdial

Matt Quigley

Why isn't "The troll starts to come towards you..." printed every turn after the player enters the same room as the troll? There is no flag that says it shouldn't, however, the attacking when: do: block is executed everyturn. Shouldn't "The troll starts to come towards ...." be executed every turn too? Are turns simply entering or leaving a room or rather any action (look, do use etc)?

Joaquin Madruga

I see it, Joaquin – fixed. Thanks! Mark Guzdial


we typed telnet machine open and that brought up the telnet screen. However we could not update it via typing in the white screen below or saying things like displayString:'Hello'. or sendLine:'hello'. Any help?

Emeka Okonkwo

Did you see me use it in class on Tuesday? Worked there. Mark Guzdial

With the TelnetMachine, how are we going to add the dependency to our models. Do we use the class TelnetMachine or the instance tm. If we use the instance, how do we display it? Also, where does the TelnetMachine handle these kind of events? I can't find any kind of messages that have change or anything else special. Jonathan D'Andries

We discussed this in class on Tuesday – perhaps you missed it. You are not going to subclass TelnetMachine nor modify it nor use an instance of it. You only really care about the method open which creates a user interface like the core of what you need to do. I started discussing the pluggable user interface components that TelnetMachine uses on Tuesday, and I'll finish them tomorrow. Mark Guzdial

What does verbMatcher do? For that matter, what does verbHandler do? Jonathan D'Andries

There is no verbMatcher in the P2 code that I see. There is a method verbMatch:do: which is a message that an AGObject understands. It takes a string of a verb to match and a block (after the do:) that should be executed when the given verb is applied to the given object. verbHandler, given the example of knife verbMatch: 'throw' do: (knife verbHandler: 'use'). "Create an alias for 'use'", must return some object which could execute for the verb 'use', but now will also execute for the verb 'throw' Mark Guzdial

Some Suggestions and Warnings

Now back to your regularly scheduled questions...

Mark Guzdial

I am having problems understanding how TelnetMachine works. You can do a TelnetMachine open, but never have to create an instance of it. You can, however, create an instance of it using new, but then you can't do an open on the instance. If you do the TelnetMachine open, how do you reference the screen that opens so that you can perform actions on it?Jason Ergle

Read the method TelnetMachine open. You will never open a TelnetMachine in your code. Not ever. (I explained this in class Thursday.) Mark Guzdial

How are you going to test or code? From the explination it sounds as though we provide everything you do 'houseWorld start' our program starts running and changes based on input correct? the reason I ask this is I want to design things differently but only if I don't get taken off for it. for instances I wanna have takeable and nontakable objects which are subclasses of AGOject..and so on is this ok? Also I would like to call my game something other than HouseWorld I am assuming this is ok as long as we specify the name of our AGWorld right? David Norvell

No, it's not okay. You may change whatever you want in P6. But in P2, P4, and P5, you must be able to run the workspace code we provide. Mark Guzdial

So NONE of what I said is allowed? So I can't make more than one type of AGObject? I can only have one and it may not have subclasses this is what you are telling me? Because I think that limiting me to that makes for a horrible disign....If my code works with the workspace given then is it ok? David Norvell

Your code must work with the workspace given. Your design must support the given interface. That's not an unusual request. Have you looked at Fall 2001 Milestone 6? Mark Guzdial


i was wondering where the example of class that used methods related to the telnetMachine was posted on the web. I searched for it but could not find it. Thanks

Emeka Okonkwo

It's A Simple UI Example. You could find it by looking at the "Changes" (button at the top of the screen) and seeing what got posted Thursday. I linked it to the Fall 2001 Class Schedule. Mark Guzdial

How do we check to see if a class is an instance of a certain class?

'=' checks to see if two classes are the exact same thing, but what checks to see if they are of the same type?


((a class) = AGObject ) ifTrue: [... ].

or you can do

( a isKindOf: AGObject ) ifTrue: [...]

Jared Parsons

Jared's right, but in general, checking the kindOf: is considered bad design. Instead, send a message to the object that you expect it to recognize, and define the same message for all the other kinds of things that it COULD be with a different response. Mark Guzdial

In typical IF games, you can have something like, put battery in

calculator. In this case, the calculator would then contain the battery, and we could take the battery back out and put it in the inventory. Would the calculator, which is an AGObject, have to be a container?

Ahmed El-Helw

Suggestion: Read through Fall 2001 Project Milestones. You'll see that containment is a requirement at P4. Mark Guzdial

kitchen to: #north attach: livingRoom. "Note the use of a symbol"

houseWorld add: livingRoom.

I can't figure out exactly what add: does. Since livingRoom already exists, and since kitchen knows about livingRoom, why does houseWorld need to have livingRoom added to it? If a room points to another room, but that room hasn't been add:'d, should it fail?

Brandon Yarbrough

World in some cases needs to look through the various rooms(talking to all players in all rooms). Without adding all of the rooms in the beginign(to a Collection of sorts) it would require a graph search to get all of the rooms. I think it's done so that you can keep a collection of rooms and not have to exhausitvely search for them Jared Parsons

Is there an easy way to tell a PlugableTextMorph what the foreground and background display colors should be? Background seems to be color: but foreground I can't find. I tried hacking through TelnetMachine but there method is much more complicated than what I am looking for. Jared Parsons

The text objects are pretty complex. My recommendation is to walk through the submorphs of PluggableTextMorph and see which one controls the foreground color. Mark Guzdial
I have walked through several components start up messages(Browser, Workspace and Transcript. I can't find a single place that they actually set the color of anything. I have been through their ugly and horrid code and I can't find it. I think that PluggableTextView controlls the foreground color but there doesn't seem to be any way to set that. Can someone give a little hint here? Jared Parsons

In the game example, what happens when the player first sees the troll and then leaves the room? It seems like the player would still die. Should we reset all flags to nil upon leaving a room?


Jonathan D'Andries

Nope, leave that...for now. (That's a bug that I realized I was putting in. Explain it semantically as the troll now chasing the player. But it's probably something to "fix" later.) Mark Guzdial

The "Simple Vocabulary" has a term for "Use". Does this mean we have to implement a generic "Use" for every AGObject even if the developer does not explicity define one?

Jonathan D'Andries

Yes. Mark Guzdial

In AGCharacter Objects when: do: messages you gave input parameters on ONLY the when: block. BUT in the description of the project you told us that EACH block in the when; do: message would be receiving the value: value: value: message passed with player, self and world. Did you just forget to put the :player :me :world | part into the do blocks??? (Look at the troll's when do block)

Squeaky Clean Squeakers

The when blocks defined do not account for leaving the room. The troll would still kill the player. Jonathan D'Andries

You should check to make sure that the character is in the same room, its specified in the directions. His check is merely redundant. Squeaky Clean Squeakers

Yes, that's a bug. Fixing now. Mark Guzdial

Earlier you stated that we would never be asked to go back and complete P1. Then you said that we would have to implement the workspace code that you provided. Am I correct in assuming that now we do have to get the block option working from P1 so that we can run your code?Jason Ergle

Why? Do I specify any rules that have blocks on them? Mark Guzdial

In the Workspace code you have provide you have knife := AGObject named: 'knife'. I don't see how this will work...Mine will work with the following change knife := AGOject new named: 'knife'. When I have the new in there it works great without it I get errors...Should this infact be in the extended example? or was this left out intitainly?David Norvell

Nevermind I figured this out named: is a class method not an instances method David Norvell

When "world quit" happens, should the UI close or mention in some way that the game is over? If it should immediately close, wouldn't the user never see the "The troll has you" message?

Sounds like you've already convinced yourself that the UI shouldn't close. Sounds like the right answer. Mark Guzdial

Earlier it was said that knife wouldn't work because it's container was the player, not the room. The same is true of kitten's use verb. me container needs to be player container as well I believe. Aaron Drew

Thanks, Aaron – fixed. Mark Guzdial

In class Prof Guzdial memtioned that a block is also an object. So where then is the class block. Also, and more to my question, where would I find a method isBlock. I have found is htmlBlock and the like but I can't seem to find this one. Thanks

Robert Schierholz

BlockContext Webb

BlockContext is the object, like Webb says. To create one, Compiler evaluate: [Transcrip show: 'This here is a block!']. Mark Guzdial

You fixed the issue where if the troll's attacking flag was nil, it would not check for the existence of the 'attacking' flag when you increment the attacking flag. However, you don't do the same for the check for death. (It is right below), is this a bug?

Squeaky Clean Squeakers

Since nil doesn't understand >, I agree. Mark Guzdial

When the PluggableTextMorph is printing information, it will occasionally go blank (after about 1 screen of input). Has anyone else had this problem, we couldn't find a refresh method anywhere.

Squeaky Clean Squeakers

Send the changed: message, and it should refresh. (Haven't seen that happen yet myself, but I don't disbelieve you.) Mark Guzdial

I have a quertion about the event handling. Our group has created the UI it contains two seperate PluggableTextMorphs, one to display text and one for the user to type his next move into. Ok here is the question: the model is from the class StringHolder and it has a method acceptContents. When our user inputs his response and presses "return" the PluggableTextMorph "eats" the event(because acceptOnCR is set for that morph) and then writes the text on the screen user input screen into the UI's model. But once it's there how will the world know that a new input string was sent by the user since the MorphicEvent was already used? Even if I modified the eventHandling for PluggableTextMorph(via subclass) I still can't say "hey send your input to some world that you don't know about". I hope I explained this well enough and any help would be greatly appreciated. thanks Jon Aquilio

It sounds to me like the problem is using StringHolder. Don't. Build your own model and make sure that it gets the input so that you can process it as you like. Mark Guzdial

I am still confused about 'use', 'take', and 'look'. It seems like the individual object of these verbs would handle them like any other verb. Its just that these particular verbs have predefined behavior. So, should we execute the predefined behavior for 'use' AND the user defined behavior? Or simply replace the predefined one with the user defined one? I mention 'use' because this is the one that was explicity redefined in the example. I am also curious about 'look' and 'take'.


Jonathan D'Andries

Yes, you handle the default case, but if there's a verbhandler, process that. A good system that user-programmers extend should have reasonable defaults, but allow for overriding of those defaults. Mark Guzdial

Will we have to handle input like this:

knife:=AGObject named:'knife'.

kitchen:=AGRoom named: 'kitchen'.

livingroom:=AGRoom named: 'living room'.

kitchen contain: knife.

livingRoom contain: knife.

How should our code handle this, or do we even need to worry about it?

Thanks, Git yo' Squeak on!

It is easier to make the legislation "an object can only be contained in one room at a time". But it would be more interesting to allow it... Like having some particular character appear throughout the game in different places. Just break it down in your OOA/D and you will be confident I think Webb

^^^ Along these lines, will we have to worry about duplicate named objects/characters/rooms in the world? This would cause a problem if the world maintains a list of all the objects/characters/rooms. This list seems apparant because we can refer to "World character: troll".

Jonathan D'Andries

You could also easily avoid this situation. Whenever a room is added to the world, scroll through all of hte characters in the room and make sure their name is not currently in the world. If it is then add something to their name to make them unique. You could also do the same check when a character or object is added to a room. Jared Parsons

We're not going to give you duplicate named objects, but you need to know if YOU care. In P5, P6, and P7, you're going to be building things with your own code. Do you think you might make that mistake? Do you think you might like to have a useful error message? You won't be graded for it, but it might make your life easier. Mark Guzdial

There is a little contradiction in the explanation of when:do:

In the example, they build the test for "me container = player container". This seems extraneous when a couple sentences down you say: "Since when:do: doesn't work except when the player is in the room"? Is it true that when:do:'s only work when the player is in the room for ALL when:do:'s or ONLY for this one in particular.

Jonathan D'Andries

You noticed that, did you? :-) I wrote the definition of when:do: after writing the code. Yes, it's extraneous, but not damaging. Mark Guzdial

So, do we reset all flags for a character if the player is not in the room?

Jonathan D'Andries

Why reset the flags? Just don't execute the when:do: until the player enters the room. Mark Guzdial

I just wanted to make sure that I understood the turnin process corectly, we only need to turnin CRC cards and UML analysis for the GUI part of our program? we don't have to worry about AGCharacter and AGWorld and all that stuff? Jason Fulghum

ABSOLUTELY NOT! You owe us OOA/D for everything you turn in in P2. Mark Guzdial

ok, that makes more sense, i was just confused by the project description saying 'CRC card analysis for every UI object', and all the other people i asked thought the same. Jason Fulghum
Oops! I see it, Jason. Fixed – thanks! Mark Guzdial

In AGObjects container method, we want to return the room containing the object. Would it be a bad idea for the object to know its location, or would it be better to search all locations for the given object?

Objects DO know their room. Object's container is its room or the player's inventory. Mark Guzdial

If we search all rooms, we're assuming that we would need a method in AGWorld to give us a list of all the rooms in the world. Otherwise, we could just ask the object for its location and return it. Is there something we're missing here? Team Rocket

Yes, you can ask the object for its location. You can also implement additional methods on AGWorld as you need them. You're not limited to what we specify. You just have to have at least that. Mark Guzdial

What is the expected action on 'world quit'? Closing the SystemWindow seems impossible without maintaining a reference to the window because the 'update:' method only does anything when you want to change the title of the window. There is a 'delete' method that works, but I need to maintain a reference to my window if this is to work.

Ok, so we probably will not be closing the window. What else should we do:
Jonathan D'Andries
Certainly, the game is ended, so stop processing input. You could tell the user to close the window. I wouldn't reset anything, or worry about deleting anything. Mark Guzdial

One error with your current example:

Some of the "world print:'s" are missing colons.

This generates errors when I paste it into a workspace and run.

Also, the "'" in don't in some of your strings throws off everything.

Another error: when you mean to create the alias "throw" for "use" on the knife object, you need to send a code block into the do: keyword, not just a value, which evaluates and generates an error.

The above example may also need [:player :me :world] parameters, just to conform to your previous example, and to our code hardcoded to conform to the standard you set forth.


Graham Coleman
I fixed all the print->print: and the don't, Graham – thanks! But I don't see where I'm sending value anywhere. Is there somewhere specific where I'm still missing :player :me :world? Mark Guzdial

I was just wondering what the '#' does in front of north?


Kyle Forkner

It makes #north a symbol. As for what a symbol is, my guess says its a simple way of comparing equality (lighter weight than a String) and also frequently specifies a method selector. These might make good keys. Graham Coleman

I was thinking has but wasn't sure. Thanks Graham
Kyle Forkner

Yes. Symbols are strings that are stored in one and only one place, i.e., all references to symbols point to the exact same object. Testing for equality means only testing the pointers – you don't have to walk the characters (like in a String). Mark Guzdial

troll when: [:player :me :world | me container = player container and: [(me flag: 'attacking') isNil] ]
do: [:player :me :world |world print: 'The troll starts to come toward you, with fangs bared and claws outstretched'.
me flag: 'attacking' value: 1].

troll when: [:player :me :world | (me flag: 'attacking') isNil not and: [(me flag: 'attacking') 5]]
do: [:player :me :world | me flag: 'attacking' value: 1 + (me flag: 'attacking').].

troll when: [:player :me :world | (me flag: 'attacking') isNil not and: [(me flag: 'attacking') >= 5]]
do: [:player :me :world |world print: 'The troll has you! You die!'. world print: 'quit'.].

The P1 milestone said that we have 5 moves before the troll get us.
However I found out that we only have 2 moves.
Here, first of all
when we enter the living room, the first when-block is active and it
is true so the do-block set the flag value to 1.
Then the second when-block is also activate because (me flag) is now not nil and flag less than 5, so the second do-block will active and increment the flag to 2.
So, we only have 2 moves left before the troll get us.
after we finish 2 of our moves, the next move will make the flag equal to 5 which will activate the third block and the troll will come and get us. Hieu Tran

Good call, Hieu! My bug. Leave it as it is – there are only two moves, then, but it sounds like your when:do: is working! Mark Guzdial

On the midterm review it was discussed that using class variables was probably bad design. If I have a class AGEvents, which contains rule about what to do on user input(ie go north) but all of the rules are spread out over multiple instances of the class is there a way to consolidate all the rules without using class variables? Robert Schierholz
Why would you be storing rules in variables for movement? If you really need to share them among all the instances, create an instance method that returns the rules. Mark Guzdial

I have a friend who came in late to the lecture where Mark Guzdial talked about the TelnetMachine interface and how to work it. I was wondering if someone could explain to me.... I mean my friend, in a nutshell, how it works, how we can use it perhaps? Charles Brian Quinn
Read the notes here – it's been said a half dozen times now. Mark Guzdial

at the very top of P2
Simple Vocabulary: Look (at), Take (the), Inventory, Quit, North, South, East, West, Quit, Use
Slightly extended vocabulary: Support Go 'roomname' or Go 'direction (e.g., Go North)

should North South East and West be commands the user can type in?
if they are, do they do the same as 'go direction' or do they describe the room in that direction?

Yes. Mark Guzdial

I did not see
go roomname as a command in the extended example...
is this required? and should it be a teleporting kind of thing, or should we check to make sure the room is adjacent before letting them go there?
That's the idea, but I didn't include an example. Yes, it is required since it's at the top of the assignment. Mark Guzdial

should every object understand the look and take verbs, or should we make the user do verbmatch: do: for them. Also, can items be more than one word and can verbs me more than one word? for example..
>look at fuzzy kitten
we wrote a wordmatcher that matches 1 or more, but is 'look at fuzzy' the verb and 'kitten' the object? or is 'look' the verb and 'at fuzzy kitten' the object? I can parse it out manually, by checking for the second word being 'at' or 'the'(for take), but then the user could create an alias 'draw and throw the' for 'use' in the knife object. Again, our parser must be rewritten. If we require that all objects characters and players be one word(using underscores for spaces), then we can say that every word but the last is the verb and the last word is the object, but I don't know if we can make that assumption. I am probably making this harder than it is, but I don't see how to get around these problems with multi-word verbs and objects, so I need to know what the deelio is.
thanx for reading.
oops..forgot my sig
Errol Summerlin
another question...why no url thingy on my name?
Errol Summerlin
Put asterisks around your name Errol, to get the "url thingy". Yes, names can have two words. How else could you distinguish the Mad Troll from the Ugly Troll? You need to deal with that. No, I don't anticipate multiple word verbs. Yes, everything should have a default response to use and take. Mark Guzdial

Perhaps someone can help me with this - I am in somewhat of a
dilemma - I can scroll the screen, in which case I lose a line of
history per scroll, or I can keep the history and force the user
to scroll. Is there a way to compromise the two? It seems to
refuse to scroll unless I remove a line from the buffer... Any
tips? Thanks.
Ahmed El-Helw
Never heard of that one before. I wouldn't worry about it. Mark Guzdial

How exactly do we destroy objects or characters. Does destroy just set all of the instance variables to nil because i tried self := nil and it says self cannot store that value.
Tim Hardcastle
Remove them from the game, not from memory. The garbage collector does that. Mark Guzdial

Under your description of AGObject you just say that it can be destroyed, you don't mention that it can die...however in your code for the kitten you call "me die" then "me destroy". So should objects be able to die and be destroyed as well as characters? Rob Boots
Looks like it. Mark Guzdial

to destroy an object, can't you just remove it from its container and not put it anywhere else?
Errol Summerlin
That's one reasonable way. Mark Guzdial

How do we put a 'cr' into a string? The reason I am askink is because when the user types 'inventory', I want to print something like.

In order to do this, I think I will need to store the output in a string and announce change again. Something to the effect of:
msOutput := msOutput, cr, newOutput.
self changed: #display

and then, display is like this:

However, this does not work. Any ideas?

Character cr asString. Mark Guzdial

Jonathan D'Andries

Upon completing Milestone 2 we discovered a few syntax errors in the sample test code. If anyone is interested in our "corrected" working test code.
Click Here
Thanks, Jesse. I'll try to get to these updates today.Mark Guzdial

Hey Squeakers, I've made a really pretty console morph out of two roundedRectangeMorphs and a textMorph and I want to save it as a new morph class complete with the default colors and sizes I've selected but when I save the class and then create a new object from it, it's just the default gray morph. What gives? Andy Foster
Classes vs. instances, Andy. Classes don't save values of things. Mark Guzdial

Can anyone give me an idea of how to work with the user interface... I have the display up and I am able to enter text and save it to the string but once I hit enter the text on the display disappears.
Tim Hardcastle
Sounds like you're not answering the message for text display correctly. Check that. Mark Guzdial

Our compiler evaluation works correctly, however, after it evaluates something it sends an error "Message is not appropriate for this object". Any ideas?

Sounds like you're sending a message to an object that it's not appropriate for. Perhaps press the Debug button and figure out what the object and the message are? Mark Guzdial

It says that there needs to be a class representing the player. If we let AGCharacter understand drop and pickup, can AGCharacter be that class?
Brandon Yarbrough
"There can never be too many classes." Have you considered defining a Player class? Mark Guzdial

One thing - in the acutal assignment, under the verbMatch: 'use' do: block, if I run the code as is, I get an error, unless I throw a pair of parens around " player container has: (world character: 'troll') " before the isTrue [in both the one for kitten and the one for knife.] Is this something that is okay [to place those parens]? Thanks.

Ahmed El-Helw
Absolutely – I didn't have an implementation to test my workspace code on, so there are certainly errors like that. Mark Guzdial

There is a problem in the block code of kitten's "use". It needs an extra set of parentheses, because right now it is sending the message has: ifTrue: ifFalse:.

Matt Quigley
Thanks, Matt. I'll try to get to them. (As you can see, the messages are fast-and-furious, and I'm still grading midterms, so I might not get the chance to update the assignment. Hopefully, people will figure the syntax errors out.) Mark Guzdial

I'm having trouble figuring out how to implement when: do:. How are the player, me, and world values passed in? Are we supposed to recognize :player as the current player, :me as the receiver object calling when:do:, and :world as the world? I'm lost, any help is appreciated.
Rod Drews (Team Rocket)
Yes, you are expected to find those objects and evaluate the block using those objects using value:with:with: Mark Guzdial

How can I check the block after when: do: [block], or verbMatch: do:[block] is well formed. Whether it is a legal block with required player, me, world parameters.

Yongjun Huang
Hmm, I don't know. We don't plan to send you illegal blocks. Mark Guzdial

In the methods needed for AGObject, there was no die method, and the kitten uses die in the example. If we are to implement die for AGObject, i'm not clear on what difference between die and destroy are (I know what they are for AGCharacter) can you have a dead knife? Valeri Pyne
See previous – both questions are answered already.Mark Guzdial

Does anyone know how to set a PluggableTextMorph to:
1. scroll when its text exceeds it window size
2. hide the cursor
3. read my mind

Andy Foster
1 should be by-default – works that way in TelnetMachine, no? See class Cursor on hiding it. Mark Guzdial

Is there a hotkey that cycles through windows?
Andy Foster
Make one? Mark Guzdial

I know I am responding wrong when displaying text... but does anyone have any suggestions on how to properly display the text in the window. Is it easier with one TextMorph... or should we use two ( a displayMorph and an InputMorph like in telnetmachine).
Tim Hardcastle
Oh, I assumed you were using two. Yes, I suggest using two like TelnetMachine. That's why I recommended TelnetMachine. Mark Guzdial

So do you recommend using the limited displayBuffer of 25 lines like telnet uses too?
Tim Hardcastle

This has been posted before but not really answered. I've created a "TelnetMachine"-like interface with two pluggableTextMorphs. When I try to call displayString: I get a messageNotUnderstood error. The same goes for when I create an instance of a TelnetMachine (test := TelnetMachine open) and call displayString: on that - messageNotUnderstood. However, if I call TelnetMachine new and then displayString it works fine but there is no UI. I guess I missed the lecture where Guzdial showed how to use displayString. Any help/ideas are always appreciated. Kevin Steely

OK I fixed the initial problem by returning the created machine in the open method. So, now when I call "test := WorldViwer open." and then "test addBoringStringInNormalMode: 'hello'." I don't get any messageNotUnderstood errors however, its not printing anything to the interface. I'm really lost as to how to update the buffer. Kevin Steely

Mark, more changes:

knife verbMatch: 'throw' do: (knife verbHandler: 'use'). "Create an alias for 'use'"

First, you need brackets around the 'do:' block.
Second, that 'do:' block needs 'player: me: world:' like all the other 'do:' block.

Graham Coleman

In the method descriptions we are supposed to turn in, what level are we writing them to? For example, should the characters method in AGRoom say, "Returns a list of characters in this room" or "Traverses a collection and checks to see if a character type is present. If so, add it to a new collection. Return the new collection."?


Lee Feagin

It does not make sense for the kitten to die!!!!! How can objects die? Above, Guzdial said that "Looks like it" when someone asked this question, but that makes no sense. What exactly should we do if the developer programs, knife die?
Jonathan D'Andries and Hing Yee Lau

If the user tries "knife die", verbMatch probably shouldn't accept "die" as a valid command. The user can't kill something by wishing it to die. The player has to use some object to kill it. And the object should know that if something acts on it in a certain way that it should kill itself.

If a knife is used on kitten, the kitten should kill itself.
If a knife is used on an apple, the apple should kill itself.

So if the apple is cut and therefore is "dead", then you should patronize the user if he tries to cut it again.

Shetu Shah

Should WordMatcher be included in the UML? For that matter, what about all the UI classes or any of the storage classes?
Jonathan D'Andries

In doing our CRC cards, I came up with a question. Should a parent class be considered a collaborator of its child class? That is if Player inherits Character for instance, is Character a collaborator of Player? Team Rocket
(world character: 'troll') die.
(world character: 'troll') description: 'A seriously dead troll']

you just killed the troll, now you make it description say that it is dead...should die set this description to 'A dead troll' also?

Should we recast dead Characters as Objects and stick them in the room, or can we have it still be a character..and just change the descriptions?

Also, I asked this question earlier, but the answer seemed ambiguous because I asked two different questions in one question...
Should go roonname allow the person using it to go to ANY room in the world? or just rooms that are adjacent and have doors into or out of them.
should a character be able to use an object that he is in the same room with?
should a character be able to look at an object in his inventory as well as those in the room?
Errol Summerlin
haha...I am having the damndest time trying to figure out how to make my textmorphs close themselves..can someone help me out?
I did diplayMorph delete, but that just makes the screen do I get them to actually what happens when you click the X?
ok when: do: should be checked once per long is a turn?
I am going to assume it is one command from the user for now, but someone please correct me if I am wrong.

I'll try to get all the last minute questions at a lumped last minute:
Mark Guzdial

Link to this Page