A Couple Questions RE: Math and Number Display

So I’ve encountered a bit of a confusing situation here, and have found nothing in the manual to help with either of these questions.
The scenario: The player can pan or mine for gold, and the gold has a cash value of $20/ounce (the approximate value of gold circa 1850) I simply need to allow the player to check how much gold or cash he has (and also intend to show both in the status bar – after I get to that section of the manual)

First one:

Gold-score is a real number that varies. Gold-score is 0.16. Cash-score is a real number that varies. Cash-score is 20 times gold-score.
However, upon compiling, Inform complains:
“Problem. The sentence ‘Cash-score is 20 times gold-score’ tells me that ‘Cash-score’, which is a real number that varies, should start out with the value ‘20 times gold-score’, but this is an object and not a real number.” … (I get the same complaint whether I write “Gold-score” or “gold-score,” so it’s not about capitalization)
I had JUST defined “gold-score” as a real number, so why is Inform thinking it’s an object?
That is quite confusing, because I tried a “work-around” for that in another section:

Requesting the cash held is an action out of world. Understand "cash" as requesting the cash held. Report requesting the cash held: Say "The cash value of your gold is $[gold-score times 20 to 2 decimal places]."
Which works just fine.

And that brings me to my second question: Is there a way to FORCE numerical display to use a specified number of decimal places?
For instance, in the example as shown so far, the player has 0.16oz of gold. That times $20 per ounce is $3.20. However, when I try to display the amount of cash, it only shown $3.2 … without including the final zero to show $3.20.
You can also use the “gold” command to show the amount of gold collected thus far, and that has the same problem.
Here’s the full code for both bits:

[code]Requesting the gold held is an action out of world. Understand “gold” as requesting the gold held.
Report requesting the gold held:
Say “So far you have amassed [gold-score to 2 decimal places] ounces of gold.”

Requesting the cash held is an action out of world. Understand “cash” as requesting the cash held.
Report requesting the cash held:
Say “The cash value of your gold is $[gold-score times 20 to 2 decimal places].”[/code]
I have read through the chapter “Numbers and Equations” in “Writing With Inform” several times, but can find nothing to help with this.
Perhaps I need to define each with units or notation? But as I understand, you can’t do math with mixed units/notations in Inform. I actually tried fiddling with that as well, but got nowhere fast.

Well, for the first part, I find it works if I take care of it in the “When play begins” block:

The library is a room. "[Gold-score] | [Cash-score]".

Gold-score is a real number that varies.
Cash-score is a real number that varies.

When play begins:
	Now Gold-score is 0.16;
	Now Cash-score is 20.00 times gold-score.

Sample Output:

Testing
An Interactive Fiction by "Phillip J Rhoades" The story headline is "A testbed"
Release 1 / Serial number 180909 / Inform 7 build 6M62 (I6/v6.33 lib 6/12N) SD

library
0.16 | 3.2

>

What the heck? o.O
Okay, that seems weird to me. I guess tho, if it works, it works. I guess I just do the calculation in-place, wherever I need it :smiley:

If cash-score is always 20 times gold-score, I think this should work:

To decide which real number is cash-score: decide on 20 times gold-score.

(I think the underlying issue is that when you’re setting the initial value of something at compile-time, you have to set it using only literal numbers, not calculations involving other things defined at compile-time. I once had something where I defined “grid size” as a constant and I wanted another constant set to grid size squared, and it didn’t work.)

For the second part, I think you can force trailing zeroes by defining money as a unit, which will also allow you to automatically put a $ in front of any monetary amount–see §15.14 of Writing with Inform.

Okay, yeah. Setting up cash-score with units does indeed force all decimal places to be shown. I had to do it like this:

Cash-value is a kind of value. $9.99 specifies a cash-value. The Cash-score is a cash-value that varies.

That other bit tho I can’t get to work. The “To decide …”
I ended up trying it this way:

To decide which cash-value is cash-score: Decide on $20.00 times gold-score.
But it always prints the cash-score as $0.00 then.
My brain is in pretzels. I think I need to give this up for today and approach it with a fresh mind tomorrow. This is very frustrating.

I think the problem is if you have both “The Cash-score is a cash-value that varies.” and the “To decide which cash-value is cash-score:” phrase. The first one setts up a global variable called “cash-score” which gets set to the default value of $0.00, and the second one sets up a function call (or something) called "cash-value’ which calculates it based on gold-score. But then every time you refer back to “cash-score” it checks the global variable and ignores the “to decide” phrase.

tl;dr: delete “The Cash-score is a cash-value that varies.” and see if that fixes the problem.

Well … Wow … I don’t even know WHAT to say about the outcome here.

To decide which cash-value is cash-score: Decide on $20.00 times gold-score.
result?

[code]>gold
So far you have amassed 0.16 ounces of gold.

cash
The total value of your gold is $11345592.32[/code]
uhhhh … WTAF o.O

Aw nuts. That looks like something related to this bug, where some real-number arithmetic is getting performed using integer operations.

Reported as a bug.

So you could go back to the old workaround, but with a routine that prints an extra zero at the end of $3.20 when needed. (This took a lot of banging on to get to work, and it still might not work.)

[code]Lab is a room.

Gold-score is a real number that varies. Gold-score is 0.16.

Requesting the gold held is an action out of world. Understand “gold” as requesting the gold held.
Report requesting the gold held:
Say “So far you have amassed [gold-score] ounces of gold.”

Requesting the cash held is an action out of world. Understand “cash” as requesting the cash held.
Report requesting the cash held:
Say “The cash value of your gold is [cash-score as a dollar amount].”

To decide which real number is cash-score:
Decide on gold-score times 20.

To say (amount - a real number) as a dollar amount:
let amount-cents be the remainder after dividing (amount times 100) by 100 to the nearest whole number; [should be divisible by 10 whenever the amount needs a trailing zero. Note that something like 4.0 gets printed with one trailing zero]
say “$”;
say amount to two decimal places;
if the remainder after dividing amount-cents by 10 is 0:
say “0”.
[/code]

Well … It’s good to know it’s a known bug, and I’m not actually just insane LOL
I’ll give your “To say as a dollar amount” solution a try. It could work well enough.
Or I could just totally ditch the whole cash conversion and let everything be payed for with raw gold. It IS in a gold mining town, after all. :wink:

Off the top of my head: what happens if you divide the cash by $1 (to get a real number), multiply by the gold weight (to get a real number), then multiply by $1 (to get a dollar amount again)? I remember using a similar workaround for this bug in the past.

I’m not really sure how to go about doing that.
Also however, to find the cash value of the gold, the gold is to be multiplied by the constant value of $20, which is then assigned to the cash-held variable. (During the California Gold Rush, gold was worth about $20 per ounce)

Right now, this is what I’ve been trying. I keep getting $0.00 as the cash-held. I find this baffling. Clearly I’m doing something wrong.
I also tried similar to how you said, and first multiplied the gold-found by 20 to get a real number, then tried multiplying by $1.00 to get a cash-value.

[code]Chapter - Gold and Cash Player Commands

Requesting the gold held is an action out of world. Understand “gold” as requesting the gold held.
Report requesting the gold held:
Say “So far you have amassed [gold-found to 2 decimal places] ounces of gold.”

Requesting the cash held is an action out of world. Understand “cash” as requesting the cash held.
Report requesting the cash held:
Say “The cash value of your gold is [cash-held]”.

To decide which cash-value is cash-held:
Let G be gold-found;
Let C be 20 times G;
Decide on C times $1.00.[/code]

This kind of sounds like you’ve defined “cash-held” as a variable again… remember that if you have a variable named cash-held it’ll override any routines you write to calculate cash-held. Once cash-held is declared as a variable you have to update it manually.

As for the other stuff I’m still stuck on the bug. Haven’t found a way to multiply or divide by $1.0 that doesn’t produce the outrageous number. There’s another couple of things I could try but honestly going to an all-gold economy might be worth trying, if it doesn’t mess up your ideas too much.

This is a hack which works around the compiler bug:

To decide what cash-value is force-convert-from-real (R - cash-value): (- REAL_NUMBER_TY_to_NUMBER_TY({R}) -).

When play begins:
	let R be force-convert-from-real 2.0 times holdings;
	say "Number result: [2 times holdings]. Real number result: [R].";

Remember to take that line out in the next release of I7 when the bug is fixed. :slight_smile:

Thanks zarf, you uber-guru you.
I’m trying to get this to work in my code, but so far, no luck.
Here’s what I’ve got (trying to replace the variables you used with the ones in my code … I prolly did it wrong):
My variable definitions:

Gold-flake is a real number that varies. Gold-grain is a real number that varies. Gold-nugget is a real number that varies. Gold-found is a real number that varies. Gold-found is 0.16. [Total of gold-flake/grain/nugget, in ounces. But I see no reason to set up a "specification" for printing that .. for now temporarily defined as a constant value] Cash-value is a kind of value. $1.99 specifies a cash-value. [Just to set up proper printing of cash-value, to force two decimal places] Cash-held is a cash-value that varies. [$20 times the gold-found]
Then, my attempt to implement your code:

[code]To decide what cash-value is force-convert-from-real (R - cash-value): (- REAL_NUMBER_TY_to_NUMBER_TY({R}) -).

When play begins:
let R be force-convert-from-real $20.0 times gold-found;
say “Number result: [20.0 times gold-found]. Real number result: [R].”;[/code]
When I tired to compile at first, as in your code there was no “$” before the “20.0 times gold-found” bit. The compiler didn’t like that at all. It complained that:

[spoiler]Problem. You wrote ‘let R be force-convert-from-real 20.0 times gold-found’ , which I tried to match against several possible phrase definitions. None of them worked.

  1. (force-convert-from-real 20.0 - arithmetic value) times (gold-found - arithmetic value)

  2. force-convert-from-real (20.0 times gold-found - cash-value)

I recognised:

force-convert-from-real 20.0 = an instruction to work out a cash-value

gold-found = a non-temporary variable, holding a real number

20.0 times gold-found = an instruction to work out a real number

Note that Inform’s kinds ‘number’ and ‘real number’ are not interchangeable. A ‘number’ like 7 can be used where a ‘real number’ is expected - it becomes 7.000 - but not vice versa. Use ‘R to the nearest whole number’ if you want to make a conversion.[/spoiler]
So to comply with the kind “cash-value” specified as $1.99, I added the “$”, but the result is clearly not correct: Number result: 3.2. Real number result: $0.00.

And now, to make matters perhaps even MORE complex …
I finally got around to putting this info into the status bar, using Emily Short’s methods in Basic Screen Effects. As such, I’ve got a table for printing the status bar, as such:

Table of Fancy Status left central right " Day [day]" "" "Gold: [gold-found]oz." " [daytime]" "[location]" " [cash-held]"
So how would I go about getting the value into there?
Sorry, I’m a total noob to Inform 7. This is my very first project in it. (Which I’m hoping to get done in time to submit to IF Comp 2018. Tho at this point, I’m doubting my ability to get it finished and tested in time. :frowning: )
Perhaps it’s just wiser to abandon the cash conversion and go with a straight-up gold economy (which wasn’t unheard of in mining towns during the California Gold Rush, apparently)

I would definitely say that if you’re trying to get this into IF Comp and you’re spending a tremendous amount of energy on something that seems peripheral to your interests in the game, it’d be a better idea to go to an all-gold economy and devote your time to the things that excite you more about your project.

Yeah. I keep letting myself get bogged down in minutia. … That or feeling overwhelmed by how much is left to be done.

This also seems to work. I think it bypasses the whole question of real numbers. The limitation is that it only manages 100ths of an ounce. I suppose you could scale at 1000, if you wanted to go deeper.

[code][Define a rate of exchange as dollars per ounce.]
An exchange-rate is a kind of value. $9.99/oz specifies an exchange-rate with parts dollars and cents.

[Get a specific rate of exchange that can be changed.]
The gold exchange rate is an exchange-rate that varies. The gold exchange rate is usually $20.00/oz.

[Use whole numbers to track ounces.]
Gold-weight is a kind of value. 1 oz specifies a gold-weight scaled at 100.

[Define a monetary data type]
Cash-value is a kind of value. $9.99 specifies a cash-value with parts dollars and cents.

[Specify unit conversion from ounces to dollars]
Gold-weight times exchange-rate specifies a cash-value.

[Track the gold carried]
Gold-score is a gold-weight that varies.

[Do the maths conversion every time cash-score is requested.]
To decide which cash-value is the cash-score:
let C be the gold exchange rate times the gold-score;
decide on C.

[Provide a way of getting the cash value of the gold carried.]
Assaying gold held is an action out of world. Understand “cash” as assaying gold held.
Report assaying gold held:
say “The gold you carry is worth [cash-score].”

[Provide a way to find out how much gold the player carries.]
Weighing the gold held is an action out of world. Understand “gold” as weighing the gold held.
Report weighing the gold held:
Say “So far you have acquired [gold-score] of gold.”

[And a way to get more gold…]
Digging for gold is an action out of world. Understand “dig” as digging for gold.
Carry out digging for gold:
let N be a random gold-weight between 0 oz and 5 oz;
now gold-score is gold-score plus N;
say “You find [N] of gold.”;
try weighing the gold held.

[Give the player some gold at startup.]
When play begins:
Now gold-score is 0.16 oz.[/code]

And here’s the story:

Nice!

Oh wow! That’s way cool. I’ll give it a shot. I had no idea that you could “specify” a vale as [something]per[something] like that. Thanks :smiley:
I had no intention of going beyond 100ths of an ounce anyhow. :wink: