String array printing issue

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

String array printing issue

Post by Flimbo »

I have a 5 chars string array. It stores a random generated password which at a certain point I print through a StringPrint command.

Everything worked fine until I had to add a further string array.
After that, StringPrint prints the first array adding a little square at the end. Why's that?

NOTE: removing the second string array, StringPrint works correctly again...
Last edited by Flimbo on Thu Dec 08, 2011 2:35 pm, edited 1 time in total.

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

Post by Roody_Yogurt »

I'm going to assume that the array that you are storing this in is long enough. How are you combining the two strings? I would do what Future Boy! does and use the "text to" function: http://hugo.gerynarsabode.org/index.php?title=Text_To

So it'd look something like this:

Code: Select all

text to (random_string_array + 5) ! so we start at the end of the string
print whatever-you-want-added-to-the-string
text to 0 ! stop writing to the string

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

Post by Flimbo »

Ehm... maybe I wasn't clear enough.
I'm not combining the two strings.

first_array contains the original random generated password

second_array is needed to store the password entered by the player with the command "type <password> on keyboard".

"Type" verb grammar forces the password to end up in word[2].
The DoType verb routine will copy word[2] in second_array and then StringCompare first_array against second_array.

StringPrint(first_array) perfectly works until I define second_array... after that, it adds a little square upon the first_array print out.

Any clue as of why that happens?


PS: I now learn from the Hugo book that there's also a StringDictCompare function to compare a dictentry (word[2]) against an array (first_array). If that works, there's no need to define second_array at all...

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

Post by Roody_Yogurt »

Ok, I don't completely understand what problem you're running into, but I know that strings in verb grammar are a big headache. You can use the "string" grammar token, but that forces the player to use quotation marks and I haven't had much success in getting the player to use them.

Anyhow, I'm going to go over the entire thing without specifically addressing your problem, but then I'll go back and change it to work off of two arrays.

First off, the grammar:

Code: Select all

verb "type"
* string "on" object				DoType
* word "on" object			DoType
(so that both >TYPE PASSWORD and >TYPE "PASSWORD" work)

Now a DoType routine that checks against password "swordfish":

Code: Select all

array typing&#91;10&#93;  ! allow 9 letter password   

routine DoType
&#123;
	local len
	"You type \"";
	if parse$ ~= -16 ! -16 seems to be the default value
		print parse$;
	else
	   print word&#91;2&#93;;
	"\" on the computer. A box pops up that says, \"";
	len = string&#40;typing,parse$,9&#41; ! write parse$ to array
	if not StringDictCompare&#40;typing,"swordfish"&#41; or word&#91;2&#93; = "swordfish" ! returns 0 if no difference
		"CORRECT!\""
	else
		"WRONG!\""
	return true
&#125;
Still, we want the game to accept any wrong word when typing passwords, yet we keep on running into that damn, "I don't know the word 'blah'" response. To get around that, we'll put something into NewParseError:

Code: Select all

replace NewParseError&#40;errornumber,obj&#41;
&#123;
     select errornumber
          case 1 &#58; &#123;
                       if word&#91;1&#93; = "type"
		         &#123;
                         DoType
		         main ! fake a turn
                         return true
			 &#125;
		      return false
		      &#125;
          case else &#58; return false
     return true
&#125;
The downside to this workaround is that we have to fake a turn passing, so if the player tries to UNDO, they'll actually UNDO the previous turn. All in all, string input in Hugo is definitely something I'd like to see improved so we wouldn't have to resort to this.

Ok, so that's all that. Now, as far as your particular situation goes, changing the StringDictCompare line to:

Code: Select all

if StringCompare&#40;typing, random_password_string_array&#41; = 0
... should work.

Of course, your question was specifically about printing, which makes me think that at least one of the string arrays was filled incorrectly. Hopefully, some of the grammar stuff above helps with that. Otherwise, maybe post some sample code and we can take a look at it.

EDIT: missed a 'return false' in the NewParseErrors routine above.
Last edited by Roody_Yogurt on Thu Dec 08, 2011 5:55 pm, edited 4 times in total.

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

Post by Roody_Yogurt »

Well, actually, let's go back to that first thing. Is the string array for the first thing large enough? A string array needs an element for each of its characters, and one extra one that holds the total number of characters, so your five-letter password should be held in a string array that is at least 6 elements.

I'm thinking that if your array is defined as "first_array[5]", StringLength (called by StringPrint) is having a hard time determining the length of the string and may print extra characters.

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

Post by Flimbo »

Re. your string comparison code, there are a couple of obscure points to me, but let's clear up the printing issue first.

Here's some minimal code to reproduce the issue.

Code: Select all

#include "hugolib.h"

array first_array&#91;5&#93;
! array second_array&#91;5&#93;

routine init
&#123;

local a

	while a<=4
	&#123;
		if random&#40;2&#41;=1		! 1=letter, 2=number
			first_array&#91;a&#93;=random&#40;8&#41;+64
		else
			first_array&#91;a&#93;=random&#40;9&#41;+48
		a++
	&#125;

	StringPrint&#40;first_array&#41;
&#125;

routine main
&#123;&#125;
The while-cycle is a cut and paste from my program.
It simply fills in a 5 items array (first_array) with a random mix of numbers (from 1 to 9) and letters (from A to H).

As it is, StringPrint prints first_array correctly.

However, if you comment out the definition of second_array at the top, recompile and run again, you'll see that StringPrint prints first_array with a little square at the end.

The reason for that must be very stupid, but for the time being, I am puzzled.

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

Post by Roody_Yogurt »

Well, it would nice if I hadn't spent so much time on the wrong path that resulted in that first post, but it looks like my post after that hits the nail on the head.

It should be first_array[6] and second_array[6]. The last element holds the length of string.

I think. To be honest, I had no experience with arrays before learning Hugo.

EDIT: Yeah, I tried the above code with 6-element arrays and the array seemed to print fine.

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

Post by Flimbo »

Yep. Printing problem solved!! :D

No time wasted at all. You helped me a lot with programming the rest.

Re. eliminating the need of quotations marks for the password, I couldn’t get your method to work at DoType level because parsing seems to have precedence over everything and gets in my way upon detection of the invalid entry.
However, I exploited your NewParseError/case 1 idea to redirect the program flow in case of word[1]=”type” and it works!

Thanks a lot!

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

Post by Roody_Yogurt »

The one issue that concerned me is that I noticed that your random-letter code provides uppercase letters (which, admittedly, looks better for printing). I hope that before you try to StringCompare that to something the player has typed in, you are making it lowercase first (since everything the player enters is understood as being lowercase).

I've also been thinking that, to get around the whole quotes/no-quotes thing, you could have >TURN ON PC do GetInput("LOGIN>>") and then GetInput("PASSWORD>>"), avoiding the issue altogether.

Anyhow, glad the other stuff is working.

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

Post by Flimbo »

Back again!
Sorry... real life prevailed for a while :-P

Thanks for both tips!
In the beginning I actually though of using GetInput for the password. Yeah, it would have been much easier, but implementing the 'type' verb was somehow mandatory... so I opted for that.

Now I'm tearing my hairs on another annoyance... I foresee an imminent new thread in this forum... eheheh

Post Reply