doEat( actor ) =
{
if (self.location <> actor)
self.doTake(actor);
if (self.location = actor)
pass doEat;
}
Anyone see any major problems with this approach?
(the article I read follows, since it's probably of some interest.)
(I slightly modified it to make it #includeable)
---------------------------------------------------------------------------
/*
Newsgroups: rec.arts.int-fiction
Path: gmd.de!Germany.EU.net!mcsun!dkuug!uts!daimi!aau!joedal
Subject: Goal-oriented behavior in TADS (LONG)
Message-ID: <joedal.740302728@dfi.aau.dk>
Sender: news@aau.dk
Nntp-Posting-Host: dfi.aau.dk
Organization: Aarhus University, Denmark
Date: Thu, 17 Jun 1993 07:38:48 GMT
Lines: 171
evans@binah.cc.brandeis.edu (Ron Hale-Evans) writes:
> [...]
> What this code does, in a nutshell, is modify the "fooditem" class so
> that any adventure using the code will treat food a little more
> intelligently, to wit: when you give the command EAT SANDWICH (or
> whatever), TADS will not respond with a message to the effect that you
> don't have the sandwich, but will GET the sandwich for you, then EAT
> it. Of course, this can be extended to other actors as well, as Mr.
> Graves points out, so that they will seem to behave intelligently too.
> With a little skull sweat, goal orientation can be made more general.
Yes, this is really a nice idea. It is rather cumbersome to have to
be so specific when playing, and it is the sort of thing that might
give newcomers the idea that IF is boring (at an occasion I demonstated
a game to my cousin; when she tried it herself it only took a moment
before she said: "Hey, do I really have to take the toothbrush before I
can use it? How stupid!").
[most of a nice little game deleted]
> modify fooditem
> doEat(actor) =
> {
> if (self.location <> actor)
> self.doTake(actor);
> pass doEat;
> }
> ;
This will work in most cases. But it may give problems in cases where
the item is not easily taken. Example transcript:
>look
You're in a bakery. On a desk is lying stables of fresh-baked bread,
reminding you of how painfully hungry you are.
>take bread
As you reach for the bread the baker stops you. "Cash first!" he demands.
>eat bread
(Taking the bread first)
The baker slaps your hand. "I know your type," he says. "You ain't gonna
get no bread until I see money!"
That was delicious!
[end of sample transcript]
You see the problem? Even if taking the fooditem gives problems it is
eaten. I'm afraid some kind of checking is needed even though it means
more complicated code.
I've fought a bit with this problem myself and have come up with what I
thought to be a solution. Unfortunately it only worked to some extend
(more details later), but it might work with TADS 2.1! I don't know
since TADS 2.1 is not out for Atari ST yet.
I'll give you the code - take it for what it's worth.
*/
// This function is supposed to be part of the general class item:
modify item
checkPossess( actor ) =
{
/* This method returns true if the actor has or can easily get
this object.
*/
if ( actor.isCarrying(self) )
return (true);
/* The actor doesn't have the object, but maybe it can just be
taken. To check this we hide the output, run the verDoTake
method, and see if it gave any output. If there WAS output
the object cannot be taken.
*/
outhide(true);
self.verDoTake( actor );
return (not outhide(nil));
}
;
/*
The function "checkPossess" is supposed to be called from ver-methods.
It returns true if the actor is already carrying this item (self) or
if it looks like this item can be easily taken.
"Easily taken" means that self.verDoTake(actor) outputs no text. This
is checked with the built-in function outhide(): outhide(true) suppresses
any output until outhide(nil) is called. outhide(nil) turns output on
again and returns true if there was any output, nil if there was no output.
Thus the effect is similar to the disambiguation mechanism in TADS.
*/
modify item
possess( actor ) =
{
/* Get this object. It is assumed that the verDoTake method has been
called and gave no output (i.e. that checkPossess has been called).
If even calling doTake don't take the object (e.g. the actor may
have got his/her hands full) the current command is exit'ed.
*/
if ( not actor.isCarrying(self) )
{
"(Trying to take <<self.thedesc>> first)\n";
self.doTake( actor );
"\n";
/* Check that the actor actually got the object - perhaps s/he
couldn't carry any more stuff!
*/
if ( not actor.isCarrying(self) )
exit; // Stop the current command
}
}
;
/*
"possess" is another function that is supposed to be part of "item".
It makes the actor possess this item (self) if possible. If this is
NOT possible the current command is aborted with exit.
This must be the time for an example. For a fooditem the general code
would be something like:
verDoEat(actor) =
{
// Is this object at hand? If not give some kind of error message.
if ( not self.checkPossess(actor) )
"You don't have <<self.thedesc>>! ";
}
doEat(actor) =
{
// Since verDoEat HAS been called for this object we are 90ure
// the object is at hand. Get it.
self.possess(actor);
// At this point the actor has the object. Because, if it was not
// available "possess" would have stopped command processing with
// an exit command.
// Here goes the code for eating. I just can't remember it in
// details!
}
That was it! The part with the baker will now be:
>eat bread
You don't have the bread!
if the baker is checked in the bread's verDoTake method. If the check is
in the doTake method the player will see:
>eat bread
(Taking the bread first)
The baker slaps your hand. "I know your type," he says. "You ain't gonna
get no bread until I see money!"
and the bread is not eaten, because the player still doesn't have the bread
after bread.possess have called bread.doTake.
So, what do you think of it?
Oh, the problem I mentioned? TADS 2.0 is confusing the user's hidden output
with its internal hidden output.
This means that if one ver-method hides the output and calls anothe ver-
method, then the output of the secon ver-method still counts as output for
the ver-mechanism. In the above case it is not a major problem: checkPossess
gives output if there was any hidden output. So whether the first (hidden)
output or the second output is detected is of little difference. But it is
left as an exercise for the reader to come up with a case where this does
casue problems.
Maybe it is fixed with TADS 2.1. At least I notified Michael J. Roberts
when I found the problem. (Any comments, Mike?)
+------------------------------------------------------------------------+
| Lars J|dal | Q: What's the difference between a quantum |
| email: joedal@dfi.aau.dk | mechanic and an auto mechanic? |
| Physics student at the | A: A quantum mechanic can get his car into |
| University of Aarhus | the garage without opening the door. |
| Denmark | -- David Kra |
+------------------------------------------------------------------------+
*/