Axe Software Forums
  Quest Developer Forum
  Me again. Question about synonyms.


Author Topic:   Me again. Question about synonyms.
Mega posted 08-10-2001 05:48 GMT     
Actually, two questions.
Firstly, I'm looking for a way to define "verb synonyms". In other words, I want "speak to", "speak", "talk to", and "talk", all to invoke the command for "speak to". One thing I figured out was to tell the game to consider "look" to be a synonym of "look at". This presented the problem of converting 'look at chair' into 'look at at chair', but I fixed that by setting 'at at' as a synonym for 'at'. However, that still doesn't solve the problem of simply typing 'look' and converting it to 'look at'. I suspect I'm going about this all wrong. Any ideas?

Ok, believe it or not, that was all part of my first question. Question 2 is about creating "room-specific" synonyms. For instance, in one room I have an object called 'iron door'. I want the command 'open door' to be read as 'open iron door'. However, another room may contain a 'wooden door', and I want the command 'open door' to handle that one correctly too. How can I do this?

Mega posted 08-10-2001 06:34 GMT          
Ok, forget the first question; I figured it out for myself :-) For anyone wondering, here's the code.

command <look #lookthing#> {
if is <#lookthing#;> then exec <look; normal>
else {
if is <$instr(#lookthing#; at_)$; 1> then exec <look #lookthing#; normal>
else exec <look at #lookthing#; normal>
}
}


The second problem, however, still eludes me. Any advice on that? :-)

MaDbRiT posted 08-10-2001 13:50 GMT          
Well if I understand what you are looking to achieve, you can do it with a combination of using aliases, synonyms and local level commands. It's harder to explain than illustrate, so here's a demo (not intended as complete in any way) that allows the iron and wooden doors of two rooms to be opened with either open door, open wooden door, or open iron door as appropriate

quote:
' Quest ASL Template

' All sections must exist in the game, though the text sections may be empty
' if desired.

define game <Enter the name of your game here>
asl-version <284>
game version <1.0>
game author <Enter your name here>
game copyright <� 2001 ...>
game info <Enter game info here>
start <startroom>
end define

define synonyms
open wooden; open iron = open
end define

define room <startroom>
look <Enter room description here>
command <open door> {
create exit east <startroom; anotherroom>
msg <The door swings open opening an exit to the east.>
}
define object <door>
look <a wooden door>
prefix <a>
alias <wooden door>
end define

end define

define room <anotherroom>
look <Enter room description here>
west <startroom>

command <open #object#> {
create exit north <anotherroom; yetanotherroom>
msg <The iron door swings open opening an exit to the north.>
}

define object <door>
look <an iron door>
prefix <an>
alias <iron door>
end define

end define

define room <yetanotherroom>
look <Enter room description here>
south <anotherroom>
end define

define text <intro>
Enter intro text here
end define

define text <win>
Enter win text here
end define

define text <lose>
Enter lose text here
end define


As I say I made no attempt to do anything here but show how to get around the synonyms problem.

Al

Computer Whizz posted 08-10-2001 20:26 GMT          
Well, not to be "cranky" in any way, but isn't that inproper useage of the naming objects?

Each object should be named differently!!

My way to get around this would be either to check the room for the alias "#whatever# door" and then just pop up a question saying "Do you mean the #whatever# door?", if not then either re-check or put up a message saying "Well, could you use the full name?" or something.....
But that door thing might cause error's later on in some way, shape or form (I like saying that sentance!! :) ).

Oh, and I thought that Alias thing is a bit much - can't you use variable's in synonyms?? Like:
look #whatever# = look at #whatever#; ect...
and some way to error check it or something?

Computer Whizz

Mega posted 08-10-2001 21:38 GMT          
Many thanx to all :-)
Alex posted 08-10-2001 21:58 GMT          
quote:

Oh, and I thought that Alias thing is a bit much - can't you use variable's in synonyms?? Like:
look #whatever# = look at #whatever#; ect...
and some way to error check it or something?

Well, no. But in your define game block you could use:

command <look at #whatever#; look #whatever#> exec <look at #whatever#;normal>

You need the "look at" first otherwise a normal "look at something" would become "look at at something", and you need the "normal" parameter to stop an infinite loop happening.

MaDbRiT posted 08-10-2001 22:32 GMT          
C.W. wrote...
quote:

Well, not to be "cranky" in any way, but isn't that inproper useage of the naming objects?
Each object should be named differently!!

Yes it is improper usage and yes you are supposed to use unique names for objects. On the other hand it works... LOL

I will admit that was quite possibly the worst thought through code I've posted here though - a real kludge! Sorry about that.

quote:

My way to get around this would be either to check the room for the alias "#whatever# door" and then just pop up a question saying "Do you mean the #whatever# door?", if not then either re-check or put up a message saying "Well, could you use the full name?" or something.....
But that door thing might cause error's later on in some way, shape or form (I like saying that sentance!! :) ).

I think as the doors are in different rooms, the problem is that it is hard to get the right effect with 'open door' 'open wooden door' and 'open iron door', just using synonyms to reduce everything to 'door' would mean that 'open wooden door' makes checking validity of the input hard and it will work on an iron door and other wierdness.

quote:

Oh, and I thought that Alias thing is a bit much - can't you use variable's in synonyms?? Like:
look #whatever# = look at #whatever#; ect...
and some way to error check it or something?

Nope. As Alex says you can't do that. However, there is a way to get the effect required without resorting to the God-Awful kludge I posted earlier.

The solution I came up with was not to alias the doors at all, using synonyms just to make sure longer descriptions are reduced to either 'wooden door' or 'iron door' respectively which is the intended purpose.

Now in my custom 'open #object#' command I check to see if #object# is 'door', and if so use a simple function to expand the description to either 'wooden door' or 'iron door' according to the room - this is literally making the assumption 'door' refers to the door actually present.

Now a test that the 'object' to be opened is present will suffice to decide whether to call the object's 'open' action.

Now 'open door' will work on the door present, be it 'wooden door' or 'iron door', but a specific 'open wooden door' will only work if the wooden door is present. I think that is what Mega was trying to achieve.

Here's my 'test' code.

quote:

define game <name of your game here>
asl-version <300>
game version <1.0>
game author <Enter your name here>
game copyright <� 2001 ...>
game info <Enter game info here>
start <startroom>
command <open #object#> do <OpenProc>
end define

define synonyms
panelled wooden door; panelled door = wooden door
heavy iron door; heavy door = iron door
end define

define room <startroom>
look <Enter room description here>

define object <wooden door>
look <a panelled wooden door>
prefix <a>
action <open> {
msg <The door swings open, revealing an exit to the east.>
create exit east <startroom; anotherroom>
}
end define

end define

define room <anotherroom>
look <Enter room description here>
west <startroom>

define object <iron door>
look <a heavy iron door>
prefix <an>
action <open> {
msg <The door crashes open, revealing an exit to the north.>
create exit north <anotherroom; yetanotherroom>
}
end define

end define

define room <yetanotherroom>
look <Enter room description here>
south <anotherroom>
end define

define function <ExpandDoor>
if (#quest.currentroom# = startroom) then set string <object;wooden door>
if (#quest.currentroom# = anotherroom) then set string <object;iron door>
return <#object#>
end define

define procedure <OpenProc>
if (#object# = door) then set string <object; $ExpandDoor$>
if here <#object#> then {
if action <#object#; open> then {
doaction <#object#; open>
}
else {
msg <You can't do that.>
}
}
else msg <I can't see that here.>
end define


That's a whole lot better than before I think...

Al

Computer Whizz posted 08-10-2001 23:30 GMT          
No, Al..... I think you mis-understood my post (which isn't hard ;) )...

OK, what I mean is (in steps!):
1. The player type's "open door",
2. Quest check's for an object,
__3. Quest checks the name or alias of the object (whatever you wish!).
__4. If this value HAS "door" in there (anywhere!) then goto step 6.... if not, goto step 2!
5. If no more objects, then msg <No door>
6. Do some internal stuff about object properties (I LOVE these!), ect...
7. Ask player <Do you mean #this# door?>. If Y goto 8. If N goto 2.
8. Do more internal stuff with object properties and do the appropriate stuff.

Do you understand now? *I* can't explain it any better, but then again I'm a; logical, computer programming, 17 (near) yr-old, male who's: high on testosterone, adrenalin, caffeene(SP?), sleepness nights (thinking about life), and college stress ("""""***FORGOTTEN***""""" ;) homework!). And am obviously very bad at social skills and ANYTHING to do with communication!
And even THAT is hard to understand!!!
;)

Computer Whizz

MaDbRiT posted 09-10-2001 08:37 GMT          
Hi C.W.

We are talking at crossed-purposes here. I was suggesting a solution for Mega's iron door in one room, wooden door in another but both must respond to 'open door', though the more specific 'open wooden door' and 'open iron door' should (obviously) only apply to the wooden door and iron door respectively.

On the other hand I think you are effectively writing about disambiguation - where you have two objects in the same room and need to find out which one the player means, that's a different thing entirely :-)

Fortunately Quest has disambiguation built in through each object's optional 'detail' tag. If you have two objects both aliased to show as 'door' in one room, Quest will recognise that and automatically generate a 'do you mean the #detail# door' or the #detail# door? dialogue.

At least that's what is supposed to happen according to Alex, I must admit to not having tried it out.

Confused? You will be after this morning's episode of S...... :-)

Al

Mega posted 09-10-2001 16:31 GMT          
Actually, you're both sorta correct. I'm looking for a way to have the user type "open door", and automatically open whatever door is in the room (if any). If there's none, then say so; if there's more than one, ask which one. But it's important that "open door" opens the correct door without further prompting, as long as there is only one door to choose from. Also, the user should be able to type "open iron door" and have the iron door open (if it's present)
Computer Whizz posted 09-10-2001 16:32 GMT          
Well..... I was more thinking about MANY rooms. And just in case you need the door objects to be checked, ect....
I always insure myself against multi-object confusion but I think it's very important to do so!
My code was just thought up for the way I think really, quick, simple and does the job you want it to.

My real purpose was for MULTI door's, in many different locations and if you wanted to control the door's in any particular way then you use something like that...

gotta GO!!

Computer Whizz

MaDbRiT posted 09-10-2001 18:56 GMT          
Mega wrote:


Actually, you're both sorta correct. I'm looking for a way to have the user type "open door", and automatically open whatever door is in the room (if any).

My code as above does this...

If there's none, then say so;

It does this too...

if there's more than one, ask which one.

As above it doesn't disambiguate - but there's only a little more work to make it do that.


But it's important that "open door" opens the correct door without further prompting, as long as there is only one door to choose from. Also, the user should be able to type "open iron door" and have the iron door open (if it's present)

The last code I posted above does do this exactly as you state. In fact the only thing it doesn't do was cater for the disambiguation needed for two doors in one room - mainly because I didn't interpret the query as requiring that :-)

Here is a version to play with that adds a second door to a room and asks which door you mean in response to 'open door'.

quote:

define game <name of your game here>
asl-version <300>
game version <1.0>
game author <Enter your name here>
game copyright <� 2001 ...>
game info <Enter game info here>
start <startroom>
command <open #object#> do <OpenProc>
end define

define synonyms
panelled wooden door; panelled door = wooden door
heavy iron door; heavy door = iron door
end define

define room <startroom>
look <Enter room description here>

define object <wooden door>
look <a panelled wooden door>
prefix <a>
action <open> {
msg <The door swings open, revealing an exit to the east.>
create exit east <startroom; anotherroom>
}
end define

end define

define room <anotherroom>
look <Enter room description here>
west <startroom>

define object <iron door>
look <a heavy iron door>
prefix <an>
action <open> {
msg <The door crashes open, revealing an exit to the north.>
create exit north <anotherroom; yetanotherroom>
}
end define

define object <closet door>
look <a typical closet door>
prefix <an>
action <open> {
msg <The door squeaks open, revealing an empty closet.>
}
end define

end define

define room <yetanotherroom>
look <Enter room description here>
south <anotherroom>
end define

define function <ExpandDoor>
set <object; door>
if (#quest.currentroom# = startroom) then set <object;wooden door>
return <#object#>
end define

define procedure <OpenProc>
if (#object# = door) then {
set string <object; $ExpandDoor$>
if (#quest.currentroom# = anotherroom) then choose <door>
}
if here <#object#> then {
if action <#object#; open> then {
doaction <#object#; open>
}
else {
msg <You can't do that.>
}
}
else msg <I can't see that here.>

end define

define selection <door>
info <Which door do you mean?>
choice <The heavy iron door> set string <object; iron door>
choice <The closet door> set string <object; closet door>
end define


I did it this way (using the code to call open actions) so that further checking for door already open etc can be built into the actions.

Al

Computer Whizz posted 09-10-2001 21:08 GMT          
Isn't it AMAZING how different people think?

.... I wouldn't have come up with that method in a million years!!

I'd have kept with object properties, a check of the alias/object name/object property.

Computer Whizz

MaDbRiT posted 10-10-2001 09:59 GMT          
C.W. observed

quote:

Isn't it AMAZING how different people think?
.... I wouldn't have come up with that method in a million years!!

It's one of the fascinating things about coding that there are almost always so many different ways to solve a problem. A solution is only ever going to be 'one way' to do it, often influenced heavily by what else you've been coding at the time - when you are in a specific 'mindset' an approach it from that angle.

Were there likely to be a LOT of doors in a LOT of rooms and a lot of rooms with more than one door, the code above would quickly get cumbersome. Personally I think the game would also get very tiresome to play then though.

That said I'd then approach the problem entirely differently, probably using a room property to flag multi doored rooms and call a reusable 'disambiguation' function, and combine that with a more sophisticated checking of the 'open door' command so that in other rooms there was effectively a check of the objects present to call the open action of anything with 'door' in its name...

Of course that code would be relatively slow running because of having to iterate through all the objects... you pays your money and takes your choice :-)

As I write this it occurs to me that another approach would be to create a function that locally overrides synonyms which would be useful for all sorts of things... There are always lots of options.

Al


Mega posted 10-10-2001 22:24 GMT          
That's exactly what I'm looking for! A function to locally override synonyms! (In fact, that's what I originally stated up top) Because I probably won't want to just open the door, I'll want to close it, look at it, knock on it, etc. And I don't want to have to make disambiguation functions for every action I want to perform. I just want to tell the compiler "If I say to do ANYTHING with a door, then do it to whatever door is present." Locally overriding synonyms would serve this purpose more effectively than anything else I can think of :-)
Computer Whizz posted 10-10-2001 22:38 GMT          
Having slept through most of the day (until 1.30-ish) then sleeping through most of the maths lesson (2 hours of non-sensickle graph cr*p.) and then sleeping from 8 till 10, I am going to say one word:

PEANUTS!!!

as that has nothing to do with the topic I am now going to THINK about this and put down some words...

yes alot of doors would be very tiresome.... but if you had a HUGE game which had near 30% of doors in it (just a rough estimate - having no relation to my game's) well you'd have many doors which might not like to be called the same name!

I'm going off to try and sleep some more before having to get some work done.

Computer Whizz

MaDbRiT posted 11-10-2001 21:51 GMT          
Mega wrote...

quote:

Locally overriding synonyms would serve this purpose more effectively than anything else I can think of

Well writing a way to do that isn't much of a problem, I have written some pretty straightforward code to do it which works fine up to where I hit what I think is a 'bug' in Quest.

Although the code as written works perfectly well, the 'objects' pane on the Quest GUI isn't updating properly and I'm left with a textual display that says 'there is a door here' and an object pane calling it a 'wooden door' or vice versa... strangely looking at the object properties proves the code is working OK - but that the object pane is out of sync' with the built in Quest variables.

Obviously you can't do a lot about that particular problem in ASL.

I'll send my code to Alex so that he can see what's happening and maybe the next 'bug fix' of Quest will solve it.

I think I've suggested this before, but an ASL command that forces the run engine to do a full refresh of all 'panes' would be nice...

Oh yes, another thing is that when running in 'outputoff' mode, Quest DOES visibly refresh the panes - which is annoying because the idea is to manipulate stuff 'out of sight' of the player. perhaps this (related) issue could be fixed too?

Al

Mega posted 11-10-2001 23:18 GMT          
Could you post the code? I'm sure it would come in useful.

Yeah, I noticed that thing with the panes. Actually, when I type the built-in command 'look', the panes DO refresh on their own. If we could look at the code built into the 'look' command, we could isolate the part that refreshes the panes, and then use it elsewhere. Any chance of doing this, Al?

MaDbRiT posted 12-10-2001 09:52 GMT          
quote:

Could you post the code? I'm sure it would come in useful.

While I can't overcome the 'refresh' problem I'll hold on to the code, because it is frustrating as hell... LOL

If/when Alex sorts the 'pane refresh' issue I'll look at the code again and 'rewrite/tidy' it - at which point I will put it in my forthcoming lib and post a 'stand alone' version on this forum.

quote:

Yeah, I noticed that thing with the panes. Actually, when I type the built-in command 'look', the panes DO refresh on their own. If we could look at the code built into the 'look' command, we could isolate the part that refreshes the panes, and then use it elsewhere. Any chance of doing this, Al?

I presume you mean to address Alex, not Al here :-) I'm not privy to Alex's Quest source code and I think this would have to be dealt with at that level, I don't think there is an ASL solution to it.

Al


MaDbRiT posted 13-10-2001 07:33 GMT          
I wrote:

quote:

Although the code as written works perfectly well, the 'objects' pane on the Quest GUI isn't updating properly and I'm left with a textual display that says 'there is a door here' and an object pane calling it a 'wooden door' or vice versa... strangely looking at the object properties proves the code is working OK - but that the object pane is out of sync' with the built in Quest variables.

Which is utter rubbish actually. :-(

While talking to Mega online I suddenly realised my code and Quest are working perfectly - I had simply written some very dumb code that doesn't actually do what I intended it to do at all!

D'Oh! One rewrite later and I have room specific synonyms working just fine.

However my test code only dealt with one room specific synonym per room, I'm going to now rework it to deal with a maximum of three or maybe five per room... more than that will slow response noticably I think.

I'll post it here once I have it working.

Al