Switching Identical Classes

This is a discussion / support forum for the Hugo programming language by Kent Tessman. Hugo is a powerful programming language for making text games / interactive fiction with multimedia support.

Hugo download links: https://www.generalcoffee.com/hugo
Roody Yogurt's Hugo Blog: https://notdeadhugo.blogspot.com
The Hugor interpreter by RealNC: http://ifwiki.org/index.php/Hugor

Moderators: Ice Cream Jonsey, joltcountry

Roody_Yogurt
Posts: 2181
Joined: Mon Apr 29, 2002 6:23 pm
Location: Milwaukee

Switching Identical Classes

Post by Roody_Yogurt »

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.

Roody_Yogurt
Posts: 2181
Joined: Mon Apr 29, 2002 6:23 pm
Location: Milwaukee

Post by Roody_Yogurt »

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:

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 &#40;a=1; a<=obj.#prop; a++&#41;
	&#123;
		if obj.prop #a&#58;  total++
	&#125;
	return total
&#125;

loafingcoyote
Posts: 89
Joined: Wed Jan 04, 2012 2:57 pm
Location: Texas

Post by loafingcoyote »

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:

Code: Select all

for &#40;j=1; j<i.#plural_of; j++&#41;

Here is the corrected routine:

Code: Select all

replace AddIdentical&#40;obj, i&#41;
&#123;
	local j

	for &#40;j=1; j<=i.#plural_of; j++&#41;
	&#123;
		if i.plural_of #j = 0           ! a blank slot
		&#123;
			i.plural_of #j = obj    ! add it
			return j
		&#125;
	&#125;
	return false
&#125;
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.

Roody_Yogurt
Posts: 2181
Joined: Mon Apr 29, 2002 6:23 pm
Location: Milwaukee

Post by Roody_Yogurt »

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.

Post Reply