Never matching parse$

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

Flimbo
Posts: 12
Joined: Sun Dec 04, 2011 2:18 pm

Never matching parse$

Post by Flimbo »

Help... I'm going nuts!

I'm comparing parse$ against some specific words, but even if it's EXACTLY the same, the comparison is never true.

What am I doing wrong?

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

Post by Roody_Yogurt »

Yeah, parse$ can be a real pain (as implied in that other thread). What verb grammar are you using for "type"? What words are you trying to match it to?

There are several things that could be going on here so I'll need that info first.

Flimbo
Posts: 12
Joined: Sun Dec 04, 2011 2:18 pm

Post by Flimbo »

Hi Roody.

This time the verb is 'press'. Here's the grammar definition:

Code: Select all

verb "press", "tap"
  *                                     DoVague
  * (kbd_keys) "on" keys_equipped       DoPress
  * (kbd_keys)                          DoPress
Both the infamous 'PC' and the 'keyboard' are suitable xobjects for the verb (in fact both have the keys_equipped attribute).
As you can guess by the grammar definition, I also coded a 'keyboard keys' object, because the player must press some specific keys in order to do some things on the pc.

Here's the object definition:

Code: Select all

scenery kbd_keys "keyboard keys"
{
	in office
	nouns "key", "keys", "button", "buttons"
	adjectives "f1", "f2", "f3", "f4", "f5", "f12", "esc", "escape", "keyboard"
	article "the"
	is plural
}
I just didn't like the standard "You don't see that." when, for instance, you try 'press f1' outside of the office location... so I changed ParseError at case 11 this way:

Code: Select all

print CThe(actor); " don't see any ";
if InList(kbd_keys, adjective, parse$)
	print "keyboard";
else
	print parse$;
print "."
RESULT: regardless of the input, InList always returns false, finding no match whatsoever between parse$ and any of the adjectives. I tried all of them.
The printout is always: "You don't see any F1" .. or similar, which is possibly even worse than "You don't see that."

I'm puzzled... again.
Last edited by Flimbo on Sat Dec 17, 2011 6:13 am, edited 1 time in total.

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

Post by Roody_Yogurt »

Whoa, that is an interesting way of doing keyboard input (using objects like that). Looks nice.

The problem I'm seeing with the Parse stuff is only not-understood words go to parse$, so checking parse$ like that isn't going to work. I'm actually kind of surprised that you are getting "F1" (or whatever else) to print at all there.

I started playing around with my own ParseError, but my initial attempts started turning into cans of worms.

There are ways to do it, but you are so, so better off just dropping the issue.

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

Post by Roody_Yogurt »

Ok, I know I said just don't do it, but hey, I like that there are questions being asked on this forum and I don't like giving up on problems too easily (even if I don't think the default response would make any regular player blink twice).

It occurred to me that this is one of the times where one could use the rarely-used using-routines-in-grammar-tokens feature.

You'd have to change your grammar to the following:

Code: Select all

 verb "press", "tap"
  *                                     DoVague
  * (CanPress) "on" keys_equipped       DoPress
  * (CanPress)                          DoPress
Then, add the following routine:

Code: Select all

routine CanPress(obj)
{
if obj ~= kbd_keys
	{
	ParseError(12, obj)
	return false
	}
elseif location = office
	return true

print CThe(actor); \
MatchPlural(actor, "doesn't", "don't");
print " see any ";
local a,b,c
a = 2
c = 2

if words > 2
{
	while a <= words
	&#123;
	a++
	if &#40;word&#91;a&#93; = "", "on"&#41;
		&#123;
		--a
		break
		&#125;
	&#125;
&#125;

b = InList&#40;kbd_keys, nouns, word&#91;a&#93;&#41;

while c <= a
&#123;
print word&#91;c&#93;; 
if c<a or &#40;a=c and not b&#41;
	print " ";
c++
&#125;

if not b
	"key";
print "."
return false
&#125;
I added code to add the word "key" to any command that didn't have it, and of course, it needs the keyboard object to be "known".

You should be able to modify that to your uses.

User avatar
Ice Cream Jonsey
Posts: 28925
Joined: Sat Apr 27, 2002 2:44 pm
Location: Colorado
Contact:

Post by Ice Cream Jonsey »

I had no idea you can do (Canpress) there. Wow.

I put in a good fight, but let's all acknowledge that Roody Yogurt is now the world's most informed Hugo programmer on earth.


TO ROODY!
the dark and gritty...Ice Cream Jonsey!

Bainespal
Posts: 151
Joined: Fri Jul 09, 2010 8:59 am

Post by Bainespal »

Ice Cream Jonsey wrote:I put in a good fight, but let's all acknowledge that Roody Yogurt is now the world's most informed Hugo programmer on earth.


TO ROODY!
*clap**clap**clap**clap**clap**clap**clap*

And ICJ is the world's best Hugo game author.

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

Post by Roody_Yogurt »

Heh, thanks.

re: the routine thing-
When I was researching grammar tokens for HxE, it took me a fair amount of time to figure out how routines-as-grammar-tokens work. When I did eventually get it working, my initial thoughts were, man, nobody is ever going to use that (since it doesn't allow redirection to a different verb routine or anything).

Despite that, I've ended up using that feature at least a couple times. In my version of Christopher Tate's conversation system. I use it so the conversation system doesn't automatically replace DoAsk, DoTell, etc., allowing both conversation options to coexist peacefully. It actually worked out quite well.

So yeah, it's not a bad trick to have up one's sleeve.

Flimbo
Posts: 12
Joined: Sun Dec 04, 2011 2:18 pm

Post by Flimbo »

Thanks Roody.

I agree with the others. That clears up how a verbroutine can be exploited as token in grammar definition.

This section of code is unclear to me, though.
Which particular case does it test?
while c <= a
{
print word[c];
if c<a or (a=c and not b)
print " ";
c++
}
I still wonder why checking parse$ against a specific word (or variable) always returns false.

Surely Kent Tessman knows.
Hopefully he's reading and let us know.

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

Post by Roody_Yogurt »

That section is for printing whatever words the player used to refer to the keyboard object (kbd_keys). Like I said, words only get set to parse$ if they are not understood (or if the expected grammar token is string and the word or phrase is in quotation marks).

So, in this case, the only way to print the exact words that the player used is to check the word array one word at a time.

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

Post by Roody_Yogurt »

Also, if the words you are checking against weren't previously declared in some object, the mere act of checking a word against parse$ (if parse$ = "slappy") *adds* that word to the dictionary table, thereby making it an understood word (which won't get stored in parse$).

Flimbo
Posts: 12
Joined: Sun Dec 04, 2011 2:18 pm

Post by Flimbo »

But here is what's happening on my screen.
I modified the pertaining ParseError section at case 11 this way:

Code: Select all

print CThe&#40;actor&#41;; \
" don't see any ";
if InList&#40;kbd_keys, adjective, parse$&#41;
	print "keyboard";
else
	print parse$;
print "."

"\nSearching parse$ among kbd_keys adjectives returns&#58; ";
print number InList&#40;kbd_keys, adjective, parse$&#41;

print "parse$ = "; parse$
print "word&#91;1&#93; = "; word&#91;1&#93;
print "word&#91;2&#93; = "; word&#91;2&#93;
"Comparison between parse$ and word&#91;2&#93; returns ";
if parse$=word&#91;2&#93;&#58; "TRUE"
else&#58; "FALSE"
... and here's a paste of the output when I type 'press esc' outside of the office location:
>press esc
You don't see any esc.

Searching parse$ among kbd_keys adjectives returns: 0
parse$ = esc
word[1] = press
word[2] = esc
Comparison between parse$ and word[2] returns FALSE
That I just don't understand.
Despite parse$ and word[2] are IDENTICAL, comparing one against the other returns false.

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

Post by Roody_Yogurt »

I don't really know why parse$ even equals 'esc' in that example, but I actually think I can help with that other thing.

word[2] is going to be filled with a dictionary entry. parse$, by definition (I think), is not a dictionary entry. When dealing with parse$, games almost always write it to a string first before doing anything else to it. In your case, I'd then use StringDictCompare.

So, something like this:

Code: Select all

array parsestring&#91;10&#93;
string&#40;parsestring, parse$, 9&#41; ! write parse$ to string 
local a
a = StringDictCompare&#40;parsestring, word&#91;2&#93;&#41;
"Comparison between parse$ and word&#91;2&#93; returns ";
if not a &#58; "TRUE"
else&#58; "FALSE" 
(not tested)

EDIT: Tested. OK, yeah, it works.

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

Post by Roody_Yogurt »

Also, I did play around with that other thing, and it seems that- for certain parse error case numbers- the engine (before ParseError is called) also throws whatever the player typed for the last object into parse$.

So, like in the above example where we are calling parse error case 11 (known object being referred to is not visible to player), parse$ gets set to whatever the player typed ("esc", "esc key", "esc button", etc.). Interestingly, the object global variable is not set at all.

Anyhow, I was trying to think of how somebody could use this feature to his advantage. Of course, the most obvious is change the style of parser error messages. I haven't yet thought of anything worthwhile and clever, though. Oh well.

Post Reply