Today, I was trying to organize my old Hugo test code, and I came across a problem I never did find a solution for. In my effort to acquaint myself with every facet of Hugo, I was playing around with identical classes.
In my test case, I had a dirty dishes identical class. The theory was, when the player washed them, they'd be removed from that class and added to the clean dishes identical class. In practice, my attempts either break the parsing so that after washing X number of dishes, it thinks I am trying to refer to the identical classes themselves, or incorrectly groups identicals.
Anyhow, I played with it some more today with no luck so far. In any case, I thought I'd throw it out here in case anybody wanted the challenge.
Switching Identical Classes
Moderators: Ice Cream Jonsey, joltcountry
-
- Posts: 2181
- Joined: Mon Apr 29, 2002 6:23 pm
- Location: Milwaukee
-
- Posts: 2181
- Joined: Mon Apr 29, 2002 6:23 pm
- Location: Milwaukee
I did recently figure this out, and to save anybody else from working on this, I'll share what I found here.
First off, it wasn't until way late in the game that I realized that AddIdentical, the routine for adding objects to identical classes, had a typo. It wasn't until I properly added objects uses Future Boy!'s AddPropValue routine and I saw it worked that it occurred to me to take a closer look at AddIdentical.
That fixed the most obvious bug (at the end of dishwashing, the PC was left with "two clean dishes three clean dishes"), but without help, referring to the three clean dishes was still redirected to the now-nonexistant dirty dishes.
Originally, I modified ParsePluralObjects so it'd check for another plural class object with a higher parse_rank so it wouldn't always go with the first identical class that shares a noun or single_noun that it is looking for.
Eventually, I decided that, in this case, I wasn't going to be using the dirtydishes class again so might as well take it out of play. ParsePluralObjects puts all identical class objects into the identical_class object itself, so I just removed it and reset its type property so it wouldn't be put back there again.
Here is some of the code:
First off, it wasn't until way late in the game that I realized that AddIdentical, the routine for adding objects to identical classes, had a typo. It wasn't until I properly added objects uses Future Boy!'s AddPropValue routine and I saw it worked that it occurred to me to take a closer look at AddIdentical.
That fixed the most obvious bug (at the end of dishwashing, the PC was left with "two clean dishes three clean dishes"), but without help, referring to the three clean dishes was still redirected to the now-nonexistant dirty dishes.
Originally, I modified ParsePluralObjects so it'd check for another plural class object with a higher parse_rank so it wouldn't always go with the first identical class that shares a noun or single_noun that it is looking for.
Eventually, I decided that, in this case, I wasn't going to be using the dirtydishes class again so might as well take it out of play. ParsePluralObjects puts all identical class objects into the identical_class object itself, so I just removed it and reset its type property so it wouldn't be put back there again.
Here is some of the code:
Code: Select all
identical_class dirtydishes "dirty dishes"
{
article "some"
plural_of dish1 dish2 dish3
noun "dishes"
single_noun "dish"
adjective "dirty"
}
identical_class cleandishes "clean dishes"
{
plural_of #3
noun "dishes"
single_noun "dish"
adjective "clean"
is known
}
routine DoWash
{
if object.identical_to ~= cleandishes, dirtydishes
"That doesn't need washing."
elseif object.identical_to = cleandishes
"That dish is already clean."
else
{
RemoveIdentical(object)
object.identical_to = cleandishes
AddIdentical(object,cleandishes)
object.name = "clean dish"
object.adjective = "clean"
if not PropertyCount(dirtydishes, plural_of)
{
"You wash the last dirty dish."
remove dirtydishes ! move it out of the identical_class object
dirtydishes.type = 0
}
else
"You wash one of the dirty dishes."
}
return true
}
routine PropertyCount(obj, prop)
{
local a, total
for (a=1; a<=obj.#prop; a++)
{
if obj.prop #a: total++
}
return total
}
-
- Posts: 89
- Joined: Wed Jan 04, 2012 2:57 pm
- Location: Texas
I finally had a chance to look at this today. I put your above code into a game with three dirty dish items, but I couldn't get it to work properly. Then I looked at AddIdentical and found the typo you were referring to:
Here is the corrected routine:
Now it works perfectly. It took me a little while to find the typo because I was stuck on "return j". I thought maybe this should return "true" instead. Then I realized returning any number above 0 is the equivalent to returning true(not just 1).
Its not surprising that no one has noticed this typo before, since you may be the first person to ever try it. I see that even objlib.h doesn't use AddIdentical. I think it's great that you're playing with plural and identical object classes. I've only had the opportunity to use them a couple of times, but I've always been impressed by how elegantly they handle manipulating multiple items.
Code: Select all
for (j=1; j<i.#plural_of; j++)
Here is the corrected routine:
Code: Select all
replace AddIdentical(obj, i)
{
local j
for (j=1; j<=i.#plural_of; j++)
{
if i.plural_of #j = 0 ! a blank slot
{
i.plural_of #j = obj ! add it
return j
}
}
return false
}
Its not surprising that no one has noticed this typo before, since you may be the first person to ever try it. I see that even objlib.h doesn't use AddIdentical. I think it's great that you're playing with plural and identical object classes. I've only had the opportunity to use them a couple of times, but I've always been impressed by how elegantly they handle manipulating multiple items.
-
- Posts: 2181
- Joined: Mon Apr 29, 2002 6:23 pm
- Location: Milwaukee
Heh, I didn't mean to make anyone go track it down themselves, but yeah, I guess I forgot to point it out here (I'm pretty sure I considered it but, I dunno, I guess I wanted to keep my code above simple or something).
I think AddIdentical is mentioned in the Hugo Book, but in any case, yeah, one of the big motivations for me to help instigate Hugo by Example is that I particularly wanted a better understanding of utility routines like that (that aren't necessarily covered all that well in the Hugo Book).
And yeah, I can't even imagine the amount of thought that goes into designing working parser routines, and Hugo's handling works remarkably well.
I think AddIdentical is mentioned in the Hugo Book, but in any case, yeah, one of the big motivations for me to help instigate Hugo by Example is that I particularly wanted a better understanding of utility routines like that (that aren't necessarily covered all that well in the Hugo Book).
And yeah, I can't even imagine the amount of thought that goes into designing working parser routines, and Hugo's handling works remarkably well.