Matching text to a variable name

I’m working on a skill system and I’ve got skills in a table correlating them to their related abilities, like so:

Table of Skill Difficulties Skill Ability Difficulty "Brawl" "Strength" 4 "Dodge" "Agility" 4 "Climb" "Strength" 5 "Spot" "Perception" 6 "Swim" "Stamina" 6

Each person has numerical values called strength, agility, etc, so a skill roll consists of looking up what ability corresponds to the skill, looking up the character’s ability score, and doing a calculation. The question is: How do I match the text in the ability field to the same-named value? Is there a way to do this other than writing a really long If statement? Alternately, is there a way to put the name of a value into a table column?

Try this.

[code]“Test”

Table of Skill Difficulties
Skill Ability Difficulty
“Brawl” “Strength” 4
“Dodge” “Agility” 4
“Climb” “Strength” 5
“Spot” “Perception” 6
“Swim” “Stamina” 6

Every turn when the turn count is odd:
say the ability corresponding to a skill of “Brawl” in the table of skill difficulties;
say line break;
say the ability corresponding to a skill of “Dodge” in the table of skill difficulties;
say line break;
say the ability corresponding to a skill of “Climb” in the table of skill difficulties;
say line break;
say the ability corresponding to a skill of “Spot” in the table of skill difficulties;
say line break;
say the ability corresponding to a skill of “Swim” in the table of skill difficulties;
say line break.

Every turn when the turn count is even:
say the difficulty corresponding to a skill of “Brawl” in the table of skill difficulties;
say line break;
say the difficulty corresponding to a skill of “Dodge” in the table of skill difficulties;
say line break;
say the difficulty corresponding to a skill of “Climb” in the table of skill difficulties;
say line break;
say the difficulty corresponding to a skill of “Spot” in the table of skill difficulties;
say line break;
say the difficulty corresponding to a skill of “Swim” in the table of skill difficulties;
say line break.

The Testing Room is A Room.

Test me with “l / l”.[/code]

You can look up the various corresponding entries in this manner.

Hope this helps.

I think this should be straightforward – just remove the quotation marks.

Climbingstars, that’s how you look up the text in the table, which is of course trivially easy. But I need to find the variable with the name that is the same as that text so that I can find the value of that variable.

Matt, I tried that. It doesn’t work.

Here’s a (non-functional) demo to illustrate what I’m trying to do; you can remove the quotes from the second column of the table to see that problem (obviously in this example we don’t really need the lookup table at all, but a more complex skill system would):

[code]The dojo is a room. Mugen is a man in the dojo. The dummy is in the dojo.

Everything has a number called the HP. The HP of Mugen is 10. The HP of the dummy is 3.

A person has a number called the Strength. The strength of a person is usually 3.
A person has a number called the Agility. The agility of a person is usually 4.
A person has a number called the Perception. The perception of a person is usually 5.
A person has a number called the Stamina. The stamina of a person is usually 2.

Table of Skill Difficulties
Skill Ability Difficulty
“Brawl” “Strength” 4
“Dodge” “Agility” 4
“Climb” “Strength” 5
“Spot” “Perception” 6
“Swim” “Stamina” 6

Instead of attacking something:
let A be the ability corresponding to a skill of “Brawl” in the Table of Skill Difficulties;
let D be the value of A for the player; [this is the line that doesn’t work]
now the HP of the noun is the HP of the noun - D;
if the HP of the noun is greater than 0:
say “A palpable hit!”;
otherwise:
say “You have utterly destroyed [the noun]!”;
remove the noun from play.[/code]

You’re touching on one of Inform’s great weaknesses. The strong typing system makes it very difficult to refer to properties in the abstract; the assumption seems to be that authors will write spaghetti code when situations like these arise.

Anyway, here’s a solution that uses spaghetti in only one place: an “initialize property correspondences rule” that assigns texts (“Strength”, “Agility”, etc.) to the number that defines the property internally. Basically, we typecast the property to a number and assign the text description of the property to the same number. We can then grab the number from either side and typecast to the value we’re after.

[code]A person has a number called Strength. A person has a number called Agility.

The strength of the player is 12. The agility of the player is 15.

Table of Skill Difficulties
Skill Ability Difficulty
“Brawl” “Strength” 4
“Dodge” “Agility” 4

Test is a room.

To decide what number is (P - a property) converted to a number: (- {P} -).
To decide what property is (N - a number) as a property: (- {N} -).

To decide what number is the skill value associated with (P - a number) of (target - a person):
(- {target}.{P} -).

Property-naming relates one text to one number. The verb to property-name (he property-names, they property-name) implies the property-naming relation.

After starting the virtual machine (this is the initialize property numbers rule):
now “Strength” property-names strength converted to a number;
now “Agility” property-names agility converted to a number.

When play begins:
choose a random row in the Table of Skill Difficulties;
let diff be difficulty entry;
say “[skill entry] tests [ability entry].”;
let P be the number to which the ability entry relates by the property-naming relation;
let V be skill value associated with P of the player;
say “Your [ability entry] score is [V].”[/code]

Related issues can be found in these threads:
https://intfiction.org/t/i7-tables-and-functional-programming/2045/1
https://intfiction.org/t/i7-typecasting-and-phrases/2080/1

I’ll try to make it work using K valued properties:

Hrm. This is valid I7 but produces invalid I6, meaning there’s almost certainly a bug in some way involved (by cursory searching, I think it’s bug 751; graham’s response there states that this kind of reasoning isn’t supposed to be well supported, but let’s press on anyway):

[code]There is room.

Table of interesting ideas
Name Idea
A text A numbers valued property
“FOO” –

When play begins:
Choose a random row in the table of interesting ideas;
Now idea entry is the carrying capacity.[/code]

And this is flat-out illegal, for reasons which I entirely fail to understand:

[code]There is room.

Table of interesting ideas
Name Idea
A text A numbers valued property
“FOO” The carrying capacity[/code]

Unsurprisingly, this is illegal:

When play begins: Let X be the carrying capacity; Showme the X of the player.

You can write this, and it will say “true”; you cannot use a variable as an intermediary, however:

When play begins: Showme whether or not the player provides a carrying capacity.

Finally, this is also illegal, and Inform has no idea why; this might be a bug, but I’m not really sure:

When play begins: Let X be the carrying capacity; Showme the total X of things which are the player.

By my limited experimentation, that is the correct way to write literal K valued properties (try “Showme the carrying capacity.” when play begins to see what I mean). I’ve run out of ideas; K valued properties probably aren’t a good way of doing this. Anyone else want to take a stab at this?

Oh, while I’ve been writing this, ektemple came up with a solution that appears to work, so you should probably use that, unless someone can make the “K valued property” approach work (since I don’t think it could fairly be described as spaghetti code).

My apologies for misunderstanding what the problem was, I got a little confused with what you were trying to get at. I took another look and came up with this.

[code]“Test”

The dojo is a room. Mugen is a man in the dojo. The dummy is in the dojo.

Everything has a number called the HP. The HP of Mugen is 10. The HP of the dummy is 3.

A person has a number called the Strength. The strength of a person is usually 3.
A person has a number called the Agility. The agility of a person is usually 4.
A person has a number called the Perception. The perception of a person is usually 5.
A person has a number called the Stamina. The stamina of a person is usually 2.

Table of Skill Difficulties
Skill Ability Difficulty
“Brawl” “Strength” 4
“Dodge” “Agility” 4
“Climb” “Strength” 5
“Spot” “Perception” 6
“Swim” “Stamina” 6

Instead of attacking something:
let A be the ability corresponding to a skill of “Brawl” in the Table of Skill Difficulties;
if A exactly matches the text “Strength” begin;
decrease the HP of the noun by the strength of the player;
otherwise if A exactly matches the text “Agility”;
decrease the HP of the noun by the agility of the player;
otherwise if A exactly matches the text “Strength”;
decrease the HP of the noun by the strength of the player;
otherwise if A exactly matches the text “Perception”;
decrease the HP of the noun by the perception of the player;
otherwise if A exactly matches the text “Stamina”;
decrease the HP of the noun by the stamina of the player;
otherwise;
say “NO MATCH!!” instead;
end if;
if the HP of the noun is greater than 0 begin;
say “A palpable hit!”;
otherwise;
say “You have utterly destroyed [the noun]!”;
remove the noun from play;
end if.

Test me with “hit dummy / l / hit mugen / hit mugen / hit mugen / hit mugen / l”.[/code]

It’s a brute force method, but it works. However, it seems that ektemple beat me to a better solution.

Inform’s functional programming capabilities don’t really help in this case, since a table can’t contain a list of properties, and so you’d still be writing spaghetti code to pass property names into your K phrases. In other words, you can’t say “Check the property name found in table cell X for the player”, you have to say “Check strength for the player”. If you want to avoid spaghetti, you need to do some hacky typecasting stuff, as in my example, to make it possible to specify properties anonymously.

(The threads that I provided also link to bug reports, and between the posts in the threads and the bug reports, I think you can find explanations of all of the questions or errors you mentioned. If you want to spend a good bit of time researching this issue, that is!)

So it looks like no matter which way you go about it, you’ll just end up listing which text matches which ability value (ie, there’s no way to take advantage of the fact that the string of characters that make up the ability name is the same as the string of characters in the text field in the table). In that case, I’d rather just use a Decide statement, like so:

[code]The dojo is a room. Mugen is a man in the dojo. The dummy is in the dojo.

Everything has a number called the HP. The HP of Mugen is 10. The HP of the dummy is 3.

A person has a number called the Strength. The strength of a person is usually 3.
A person has a number called the Agility. The agility of a person is usually 4.
A person has a number called the Perception. The perception of a person is usually 5.
A person has a number called the Stamina. The stamina of a person is usually 2.

Table of Skill Difficulties
Skill Ability Difficulty
“Brawl” “Strength” 4
“Dodge” “Agility” 4
“Climb” “Strength” 5
“Spot” “Perception” 6
“Swim” “Stamina” 6

To decide which number is the score of (T - some text) for (P - a person):
if T is “Strength”, decide on the strength of P;
if T is “Agility”, decide on the agility of P;
if T is “Perception”, decide on the perception of P;
if T is “Stamina”, decide on the stamina of P;
decide on 0.

Instead of attacking something:
let A be the ability corresponding to a skill of “Brawl” in the Table of Skill Difficulties;
let D be the score of A for the player;
now the HP of the noun is the HP of the noun - D;
if the HP of the noun is greater than 0:
say “A palpable hit!”;
otherwise:
say “You have utterly destroyed [the noun]!”;
remove the noun from play.[/code]

A recent question is related to this old thread, which I think is worth reviving for two reasons:

  1. This type of setup almost works in 6M62, and the reasons that it doesn’t seem to have less to do with any inherent limitations and more to do with the compiler’s ability to parse property names in certain contexts.

  2. Code that works around this in 6M62 won’t work at all in 10.1.2, which may be a regression.

Why this looks like a table parsing problem in 6M62

The OP’s goal was to create a table linking skills to particular properties. Any of these properties would always be a number valued property, so the kind of value is pretty specific.

A table like this will not be accepted in 6M62:

Table of Alt Skill Difficulties
Skill	Ability (number valued property)	Difficulty
brawl	strength	4
dodge	agility	4

However, a table like this will be (if the skills are first defined elsewhere):

Table of Alt Skill Difficulties
Skill	Ability (number valued property)	Difficulty
brawl	--	4
dodge	--	4

and in fact it will be possible to assign property values to the empty fields at run-time. For example, in 6M62:

When play begins:
	choose row 1 in Table of Alt Skill Difficulties;
	now the Ability entry is strength;
	choose row 2 in Table of Alt Skill Difficulties;
	now the Ability entry is agility;
	showme the contents of Table of Alt Skill Difficulties;

will yield

Table of Alt Skill Difficulties
(row 1)  | brawl | property 271 | 4 |
(row 2)  | dodge | property 272 | 4 |

and those are the correct property IDs, as can be seen with:

showme strength;
showme strength of player;
showme agility;
showme agility of player;

yielding

numbers valued property: property 271
“strength of player” = number: 5
numbers valued property: property 272
“agility of player” = number: 3

This implies that the template code for tables is capable of handling this type of column, but the parser for table rows is not prepared to read the name of a property as a table column value in the same manner that it would for a showme statement.

The following when play begins rule (with a small I6 workaround for the compiler’s unwillingness to recognize a <table column> of <object> phrase) pretty much works to get the table setup being sought, and should allow definition of phrases making use of the stored property:

To decide which number is (stat - number valued property) for (P - person): [note "for" not "of"]
	(- ({P}.({stat})) -).

When play begins:
	choose row 1 in Table of Alt Skill Difficulties;
	now the Ability entry is strength;
	choose row 2 in Table of Alt Skill Difficulties;
	now the Ability entry is agility;
	showme the contents of Table of Alt Skill Difficulties;
	showme strength;
	showme strength of player;
	showme strength for player;
	showme agility;
	showme agility of player;
	showme agility for player;
	showme ability entry;
	[showme (ability entry) of player;] [6M62 compiler doesn't accept, but it could]
	showme (ability entry) for player;

(EDIT: removed incorrect comment about out-of-memory error in previous code block; that happened in an earlier version but not in what’s posted here.)

Possible regression in 10.1.2

The 10.1.2 compiler doesn’t like the code here at all. Attempting to compile the Table of Alt Skill Difficulties results in an internal error, so it’s not possible to do a very good comparison between the two versions.

However, as shown by the 6M62 notes above, it certainly seems like a viable option for the compiler to do a better job of handling properties as first-class values in a way that would be beneficial to this type of scenario and others like it.

Sample code

For reference, here’s the full scenario that I was playing with:

Brawl and Dodge
"Brawl and Dodge"

Lab is a room.

A person has a number called strength.
A person has a number called agility.

Skill is a kind of value. Some skills are brawl and dodge.

Table of Alt Skill Difficulties
Skill	Ability (number valued property)	Difficulty
brawl	--	4
dodge	--	4

To decide which K is (stat - arithmetic value of kind K valued property) for (P - person): [note "for" not "of"]
	(- ({P}.({stat})) -).

When play begins:
	choose row 1 in Table of Alt Skill Difficulties;
	now the Ability entry is strength;
	choose row 2 in Table of Alt Skill Difficulties;
	now the Ability entry is agility;
	showme the contents of Table of Alt Skill Difficulties;
	showme strength;
	showme strength of player;
	showme strength for player;
	showme agility;
	showme agility of player;
	showme agility for player;
	showme ability entry;
	[showme (ability entry) of player;] [6M62 compiler doesn't accept]
	showme (ability entry) for player;

The strength of the player is 5. The agility of the player is 3.