Return to text-to-number conversions

A follow-up question or two about converting digits-as-text to a number. This was the recommended solution last time, and it works great!

To decide what number is the numerical equivalent of (digits - text):
	let Z be the player's command;[this is a backup of the 'real' player's command]
	let N be -1;
	change the text of the player's command to digits;[now make the player's command our text]
	if the player's command matches "[number]":[magic]
		let N be the number understood;
	change the text of the player's command to "[Z]";[change player's command back]
	decide on N.

I’ve got a snag doing this after reading a command (which might make sense, since we are already messing with the player’s command). This:

lab is a room.

after reading a command:
	let t be the player's command in lower case;
	if t matches the regular expression "(frob|f)(\s| to )(\d+)":
		let digits be "[text matching subexpression 3]";
		let N be the numerical equivalent of digits;
		say "frobbing [N].";
		let R be N + 5;
		say "N + 5 = [R].";
		say "[the player's command]";
		try jumping;

Yields up this:

rules output
>frob 3
[Rule "after reading a command" applies.]
frobbing 3.
N + 5 = 8.
frob 3
[Rule "announce items from multiple object lists rule" applies.]
[Rule "set pronouns from items from multiple object lists rule" applies.]
[Rule "before stage rule" applies.]
[Rule "basic visibility rule" applies.]
[Rule "basic accessibility rule" applies.]
[Rule "carrying requirements rule" applies.]
[Rule "instead stage rule" applies.]
[Rule "requested actions require persuasion rule" applies.]
[Rule "carry out requested actions rule" applies.]
[Rule "descend to specific action-processing rule" applies.]
[Rule "work out details of specific action rule" applies.]
[Rule "investigate player's awareness before action rule" applies.]
[Rule "player aware of his own actions rule" applies.]
[Rule "check stage rule" applies.]
[Rule "carry out stage rule" applies.]
[Rule "after stage rule" applies.]
[Rule "investigate player's awareness after action rule" applies.]
[Rule "report stage rule" applies.]
[Rule "report jumping rule" applies.]
You jump on the spot.
[Rule "last specific action-processing rule" applies.]


*** Run-time problem P39: Attempt to say a snippet value which is currently invalid: words 1 to 2.

It gets pretty far down the road before sputtering out! It’s very possible that I’ve just been looking at this too long and am missing something obvious. What’s going on here?

edit: while I think the word replacement is the better solution, this particular run-time error can also be resolved by adding an explicit change to the player’s command after checking the regexp, i.e.,

	if t matches the regular expression "(frob|f)(\s+)(\d+)":
		replace the player's command with "blarg";

There’s already an I6 function to translate one word of the player’s command into an integer.

To decide what number is player-word-as-number (N - number): (- TryNumber({N}) -);

After reading a command:
	let t be the player's command in lower case;
	if t matches the regular expression "(frob|f)(\s+)(\d+)":
		let N be player-word-as-number 2;
		say "Frobbing number [N]...";
		reject the player's command;

>frob 175
Frobbing number 175…

This is fussy because you need to know the word number. In this example, I simplified your regexp to just “f/frob N” (eliminating the option of “frob to N”) so that I could be sure the number would always be word 2. Really, this still isn’t reliable:

>jump. frob 17
Frobbing number -1000…

The -1000 means that it didn’t parse right, because word 2 of the player’s command isn’t the integer here.

1 Like

This is the general case of text-to-integer. I suspect this has been posted before, but I couldn’t find it so here it is:

Include (-

[ Text_Parse_Number txt   cp p len ch ix val minus;
	cp = txt-->0; p = TEXT_TY_Temporarily_Transmute(txt);
	len = TEXT_TY_CharacterLength(txt);
	
	ix = 0;
	ch = BlkValueRead(txt, ix);
	if (ch == '-') {
		minus = true;
		ix++;
	}
	
	while (ix < len) {
		ch = BlkValueRead(txt, ix);
		if (ch < '0' || ch > '9') {
			print "**ERROR: not a number**^";
			val = -1;
			minus = false;
			break;
		}
		val = val * 10 + (ch - '0');
		ix++;
	}

	TEXT_TY_Untransmute(txt, p, cp);
	
	if (minus) val = -val;
	return val;
];

-);

To decide what number is parse-int (T - text): (- Text_Parse_Number({T}) -);

This prints a runtime error if the text contains non-numeric characters. You could gussy this up to permit whitespace, or flag errors some other way.

4 Likes

OK! I’ll go bang at this a bit then come back. Thanks!

1 Like

OK, the -1000 is something that can be checked, which can clarify some behavior with compound commands. Solved!

some code
After reading a command:
	if t matches the regular expression "(frob|f)(\s+to\s+)(\d+)":
		now N is player-word-as-number 3;
		if n is not -1000:
			say "frobbing [N]...";
		otherwise:
			say "The 'frob' action cannot be used as part of a compound command.";
		reject the player's command;

after reading a command:
	if t matches the regular expression "(frob|f)(\s+)(\d+)":
		now N is player-word-as-number 2;
		if n is not -1000:
			say "frobbing [N]...";
		otherwise:
			say "The 'frob' action cannot be used as part of a compound command.";
		reject the player's command;

Thanks.