[I7] Names of values clashing with names of actions.

Here is the relevant code:

[code]Game Room is a room.

A scene can be gamelike.
Choosing a Game is a scene. BJ is a scene. FCD is a scene. W is a scene. TH is a scene. GF is a scene.
BJ, FCD, W, TH, and GF are gamelike.

Cardgame is a kind of value. The cardgames are nogame, Blackjack, Five Card Draw, War, Texas Hold Em, and Go Fish.
Understand “black” or “jack” or “black jack” as blackjack. Understand “five” or “card” or “draw” or “five card draw” or “five card” as Five Card Draw. Understand “texas” or “hold em/them” or “texas hold em/them” as Texas Hold Em. Understand “go” or “fish” or “go fish” as Go Fish.

Current game is a cardgame that varies. Current game is nogame.

Picking a game is an action applying to one value. Understand “let’s play” or “lets play” or “choose” as “[play]” when Choosing a Game is happening. Understand “game of” or “round of” or “hand of” as “[game of]” when Choosing a Game is happening. Understand “a [game of]” as “[a game of]” when Choosing a Game is happening. Understand “a” or “some” as “[some]” when Choosing a Game is happening. Understand “[a cardgame]” or “[play] [a cardgame]” or “[play] [a game of] [a cardgame]” or “[some] [a cardgame]” or “[play] [some] [a cardgame]” as picking a game when Choosing a Game is happening.

Understand “pick [a cardgame]” or “play [a cardgame]” or “play [some] [a cardgame]” or “pick [some] [a cardgame]” or “play [a game of] [a cardgame]” or “pick [a game of] [a cardgame]” as picking a game when Choosing a Game is happening.

Carry out picking a game:
if the cardgame understood is:
– Blackjack:
now the current game is BlackJack;
– Five Card Draw:
now the current game is Five Card Draw;
– War:
now the current game is War;
– Texas Hold Em:
now the current game is Texas Hold Em;
– Go Fish:
now the current game is Go Fish.

Choosing a Game begins when play begins. Choosing a Game ends when current game is not nogame… BJ begins when current game is Blackjack. FCD begins when current game is Five Card Draw. TH begins when current game is Texas Hold Em. W begins when current game is War. GF begins when current game is Go Fish.

When a gamelike scene begins:
say “Alright, [current game] it is.”

When Choosing a Game begins:
say “‘What do you want to play: Blackjack, Five Card Draw, War, Texas Hold Em, or Go Fish?’”.

Instead of doing something other than picking a game during Choosing a Game:
say “It’s not the time for that. Pick a game: Blackjack, Five Card Draw, War, Texas Hold Em, or Go Fish.”;

[/code]

But it doesn’t work properly when the player types “go fish” or “hold em” I assume because the game matches the command to the going and the taking actions. How do I fix this?

Any advice would be greatly appreciated!

This should work, but there might be a more elegant solution someone with more experience could offer:

Understand "texas" or "hold_em/hold_them" or "texas hold em/them" as Texas Hold Em. Understand "go_fish" as Go Fish.

After reading a command while the player's command includes "go":
	if "[the player's command]" matches the regular expression "^(?i)go$" or "[the player's command]" matches the regular expression "^(?i)go fish$":
		let T be "[the player's command]";
		replace the regular expression "^(?i)go fish$" in T with "go_fish";
		replace the regular expression "^(?i)go$" in T with "go_fish";
		change the text of the player's command to T;

After reading a command while the player's command includes "hold":
	if "[the player's command]" matches the regular expression "^(?i)hold em$" or "[the player's command]" matches the regular expression "^(?i)hold them$":
		let T be "[the player's command]";
		replace the regular expression "^(?i)hold em$" in T with "hold_em";
		replace the regular expression "^(?i)hold them$" in T with "hold_them";
		change the text of the player's command to T;

So, the code doesn’t actually understand “hold em”, but “hold_em”, and you fix the player’s command up for them behind the scenes with some regex trickery. Again, regex are performance heavy (but it shouldn’t matter too much here) and someone more advanced than I might have an even better solution for you.

Thanks for the quick response dootdoot! After I posted this, I was catching up on some of the forum posts and saw one to do with the reading a command activity (which I never think to use), and I ended up with a solution very similar to yours. I now have added:

After reading a command during Choosing a Game: if the player's command matches "[a cardgame]": replace the player's command with "play [cardgame understood]";

This works fine, but it just feels like there ought to be a better way to handle this. Does anyone have any alternate solutions?

I think that your solution is probably the best; at least it was what I was going to suggest – except that I wouldn’t count on “[cardgame understood]” being set before the command is parsed; I’m curious why your code actually works. (You could just take the player’s command and put "play " in front of it; that might be more robust to subsequent changes in Inform.)

It does seem as though there should be a better way to handle this but I doubt that there is. The Inform parser takes care of a lot of things by checking to see if the first work of the command is a verb, and allowing alternate stuff to happen only when there’s no verb. For instance, when responding to a disambiguation prompt (“What do you want to examine, the red book or the blue book?”), if the first word entered is a verb it treats it as a new command, and if the first word entered isn’t it puts your answer back into the original command and tries to process it.

And, more relevant to your case, it won’t try to check whether your command is a noun that matches noun-only commands unless the first word isn’t a verb; if it’s a verb it just processes it as the appropriate command and there’s no going back. So getting the parser to process “go fish” as the name of a game when it’s on its own would require modifying the parser in Inform 6 somehow. There’s a bit of code (at least there was in 6G60) that you can modify to tell Inform that some verbs are also used as names, but I don’t think it works for this case, only for the disambiguation responses.

Looking at your code, though, there may be simpler solutions. It doesn’t look like you actually want to allow normal processing of actions during Choosing a Game at all. So you could look at the example “Baritone, Bass” in the manuals, which gives you a way to make the player answer a question and reject everything that isn’t an answer. Also, your “Carry out choosing a game” rule is more complicated than it needs to be; you could just write “Now the current game is the cardgame understood.” Finally, you may notice that the initial room description doesn’t appear; this is because it’s printed by an automatic look action at the beginning of the game, and your “instead of doing something other than picking a game…” rule overrides that.

Thank you so much matt w! That was exactly the information I was looking for. I don’t know anything at all really about I6, so for now I’ll need to be satisfied with this solution.

As for the other suggestions, my code is a good bit more complicated than what I posted here, so the Baritone, Bass example doesn’t really suit my needs. The Choosing a Game scene doesn’t actually start when play begins (that was just something I added for the post after stripping it down) so it doesn’t negatively affect my initial room description. However, the bit about my carry out rule was spot on; I can’t believe that my first thought was a switch statement rather than directly assigning the value.

As far as adding “play” to the beginning of a player’s command, I didn’t do that because then it would only properly recognize the noun only command and not things like “play go fish”. It would parse “play play go fish”.

Can you elaborate a bit on what you said:

I didn’t even consider that would be an issue.

Thanks again for all the information!

One quick related question: I feel like I could get this to work in more the way I’d like if I could add a conditional when clause to the end of the statement:

Understand the command "whatever" as something new.

But as I understand it, this is disallowed.

Is there a way to achieve this functionality without using I6 (which I doubt)? And does anyone know the rational behind not allowing this?

That isn’t really an understand statement: it’s a way of telling the compiler to completely forget the grammar lines for a particular verb. Thus the fancy things you can do with understand statements don’t work here.

Well, what I meant here was that you should do this only when the player’s command consists only of the cardgame. This should work:

After reading a command during Choosing a Game: if the player's command matches "[cardgame]": replace the player's command with "play [the player's command]".

(“Matches” here means it’s an exact match. Unfortunately there are two different kinds of matching in Inform; when you’re comparing a snippet like the player’s command to a topic, “matches” means matches exactly and “includes” means includes, as in section 18.33 of Writing with Inform. When you’re comparing one text to another, “matches” means includes and “exactly matches” means matches exactly, as in section 20.5. This annoys me, but it’s something you’ll have to learn–or, like I do, look up every time you can’t remember it.)

Well, I confess I don’t really know exactly what’s going on here. But officially I think things like “the [value of whatever kind] understood” aren’t supposed to be set until the command has been parsed into an action, which happens after the After reading a command rules run. At least that’s what it sounds like in section 17.9 of Writing with Inform. It seems as though in fact it’s getting set whenever a “[cardgame]” token is getting matched, even in an “If the player’s command matches” line, but I wouldn’t necessarily count on that behavior staying the same in future versions of Inform.

The “[value] matched” variable is set every time a token of that value is successfully parsed, so unless those parsing routines are replaced, it should be safe to access them immediately after a matching test.

One other thing to note: “GO FISH. DEAL. ASK FOR THREES.” will still cause the error, because the “after reading a command” rule looks at the entire command and doesn’t see an exact match.

Ah good catch Draconis. I never use multiple commands at once so I tend not to consider it. I have now reworked it. I realize that unlike what I had before, it allows weird orderings like “some round of pick go fish”, but I can live with that.

Does anyone see any possible issues with this:

[code]Game Room is a room.

A scene can be gamelike.
Choosing a Game is a scene. BJ is a scene. FCD is a scene. W is a scene. TH is a scene. GF is a scene.
BJ, FCD, W, TH, and GF are gamelike.

Cardgame is a kind of value. The cardgames are nogame, Blackjack, Five Card Draw, War, Texas Hold Em, and Go Fish.
Understand “black” or “jack” or “black jack” as blackjack. Understand “five” or “card” or “draw” or “five card draw” or “five card” as Five Card Draw. Understand “texas” or “hold” or “hold em/them” or “texas hold em/them” as Texas Hold Em. Understand “go” or “fish” or “go fish” as Go Fish.

Current game is a cardgame that varies. Current game is nogame.

Picking a game is an action applying to one value. Understand “play” or “pick” or “let’s play” or “lets play” or “choose” as “[play]” when Choosing a Game is happening. Understand “game of” or “round of” or “hand of” as “[game of]” when Choosing a Game is happening. Understand “a [game of]” as “[a game of]” when Choosing a Game is happening. Understand “a” or “some” as “[some]” when Choosing a Game is happening.

Understand “play [a cardgame]” as picking a game when Choosing a Game is happening.

Carry out picking a game:
now the current game is the cardgame understood;

After reading a command during Choosing a Game:
if the player’s command includes “[some]”:
cut the matched text;
if the player’s command includes “[play]”:
cut the matched text;
if the player’s command includes “[a game of]”:
cut the matched text;
if the player’s command includes “[a cardgame]”:
replace the matched text with “play [cardgame understood]”;

Choosing a Game begins when play begins. Choosing a Game ends when current game is not nogame. BJ begins when current game is Blackjack. FCD begins when current game is Five Card Draw. TH begins when current game is Texas Hold Em. W begins when current game is War. GF begins when current game is Go Fish.

When a gamelike scene begins:
say “Alright, [current game] it is.”

When Choosing a Game begins:
say “‘What do you want to play: Blackjack, Five Card Draw, War, Texas Hold Em, or Go Fish?’”.
[/code]

No. Obvious problem with “go fish. pick up thing”. This is way harder than I thought. It seems like more functionality for dealing with multiple command inputs would be a kind of useful to have built in. Like a “processing multiple commands” flag and snippet variables for player’s first command, player’s second command, etc.

The trick is that the commands aren’t separated until they’re being parsed, and you need to modify the command before giving it to the parser.

I’m a bit out of my depth on this now, so forgive me. But, what about a function or something which could, when called, send the command to the parser “out of world” so to speak, so that you could then ask questions about how and what it understood, or rather will understand when it is parsed in the game. Would that be a feasible thing to implement?

Not without some serious hacking, I don’t think. I did something a little bit like that once (under certain circumstances, if you hit a parser error you could send it back to be reparsed a different way) but that depended on Ron Newcomb’s Original Parser extension, which translated the parser from an older version of Inform into Inform 7, and that’s not available anymore. Plus it was a pretty tough hack (for me) and it wound up buggy.

If “go fish. pick up thing” is a real problem for you one solution you could try is to see if you can use text matching (regular expressions or something) to check whether the name of the cardgame is at the beginning of the command, and only then insert play. Another really kludgy thing is to try to turn “go fish” and “hold em” into verbs rather than nouns, defined as special actions that get redirected to picking the game you want:

Special picking GF is an action applying to one cardgame. Understand "go [cardgame]" as special picking GF. Check special picking GF when the cardgame understood is not go fish: say "You can only pick one card game!" instead. Carry out special picking GF go fish: try picking a game go fish.

This actually processes “go fish” as the verb “go” and the game “go fish” (referred to only as “fish”); once that gets to our special action we just redirect it to the action of picking a game go fish (since your original action name is “picking a game” we wind up with this weird formulation when we want to state the noun). Similarly for Texas Hold Em:

Special picking TH is an action applying to one cardgame. Understand "hold [cardgame]" as special picking TH. Check special picking TH when the cardgame understood is not Texas Hold Em: say "You can only pick one card game!" instead. Carry out special picking TH Texas Hold Em: try picking a game Texas Hold Em.

Note that you have to add “em” by itself to your understand list for Texas Hold Em, so that “hold em” can be understood as the verb “hold” plus Texas Hold Em. Also we needed those check rules so “go draw” gives an error, as it should.

And you have to modify the rule that blocks your actions:

Instead of doing something other than picking a game or special picking GF or special picking TH during Choosing a Game:

Might need more tweaks as well. This is an ugly kludge but it might work.

Yeah. I figured it would have been done already unless it was crazy difficult. That last suggestion actually seems like it will fit my needs best and it took only minutes to get it working. Thanks matt w! And thank you to everyone for the advice and the explanations of everything. The manuals are great but the forum is invaluable when it comes to these kinds of questions.

The best way to do this is probably the same way Infocom implemented spells in the Enchanter Trilogy:

Selecting go fish is an action out of world applying to nothing. Understand "go fish" or "[select] go fish" as selecting go fish.
Selecting blackjack is an action out of world applying to nothing. Understand "blackjack" or "[select] blackjack" as selecting blackjack.
[etc.]

Actions applying to kinds of value are great, but they aren’t always helpful.

EDIT: Oops, didn’t see the second page. This is basically what Matt is suggesting.

The “go [cardgame]” thing is in some ways clunkier than having “go fish” itself understood as picking go fish (especially because “go [go fish]” can’t be understood, apparently–the action has to be defined on a whole cardgame or it won’t compile. The idea behind my approach was that it gets you more of the understanding machinery, so the player might not have to type the exact string you’ve programmed in, but the machinery for understanding values isn’t as sophisticated as the machinery for understanding things–for instance, I don’t think it disambiguates, and it doesn’t automatically understand every word in the name (if you have a thing called “bright silver key” the game will automatically understand “bright key,” “silver key,” etc., but for your card games you have to type out the exact name or something in one of the Understand lines).

So it might not actually be any less work to list all the ways of referring to Go Fish in the Understand line for selecting Go Fish, as Draconis has it, than to wind up typing them all out in the Understand line for the game, as I have it. It might depend on whether there’s another context where the player needs to refer to the game (in which case you’d need the Understand lines for the game anyway).