Table with identical columns and rows

I’m poking around with Inform for the first time in like a decade. Is it possible to have a table where the column and rows are the same values? If so how do I look things up?

I have a table with some pots of paint and a bowl where they can be mixed. I want the player to add some paint to the bowl then have the color update based on the existing color and what was added. A table seemed the simplest way but I can’t figure out how to get to the correct result.

The Lab is a room.

Color is a kind of value. The colors are red, blue, yellow, green, orange, purple, brown, and white.

In The Lab is a supporter called the desk.

Paint is a kind of thing. Paint has color. Paint is usually white.

An open container called the bowl is on the desk.  In the bowl is some paint called BowlPaint.

A pot is a kind of container. A pot is always open. A pot can be pourable. A pot is always pourable. A pot has color.

The description of a pot is "a pot of [color] paint."

On the desk is a red pot. On the desk is a blue pot. On the desk is a yellow pot. On the desk is a green pot. On the desk is a orange pot. On the desk is a purple pot. On the desk is a brown pot. On the desk is a white pot. 

Understand "pour [something]" as pouring. Pouring is an action applying to one thing.

Table of Mixing
color	red	blue	yellow	green	orange	purple	brown	white
red	red	purple	orange	brown	red	red	brown	red
blue	purple	blue	green	blue	brown	blue	brown	blue
yellow	orange	green	yellow	yellow	yellow	brown	brown	yellow
green	brown	blue	yellow	green	brown	brown	brown	green
orange	red	brown	yellow	brown	orange	brown	brown	orange
purple	red	blue	brown	brown	brown	purple	brown	purple
brown	brown	brown	brown	brown	brown	brown	brown	white
white	red	blue	yellow	green	orange	purple	white	white

Carry out pouring:
	let C be the color of the noun;
	let B be the color of BowlPaint;
[at this point I'm lost]

How do I find the correct intersection of colors then say “now BowlPaint is [that intersection]”? Am I going about this entirely wrong?

3 Likes

As far as I know, there’s no way to iterate through the columns of a table. One can only iterate through rows, so the data structure of the table that you’ve laid out isn’t the easiest to work with. The compiler certainly doesn’t understand it the way that you seem to intend, as can be seen by looking at the Index (under Contents/Tables).

I would recommend a table with three columns, structured like so:

Table of Mixing
previous	new	resulting mix
red	red	red
red	blue	purple
red	yellow	orange
red	green	brown
red	orange	red
red	purple	red
red	brown	brown
red	white	red
blue	blue	blue
blue	yellow	green
blue	green	blue
blue	orange	brown
blue	purple	blue
blue	brown	brown
blue	white	blue
...
[add rows as needed]

That way you can talk about the previous entry, the new entry and the resulting mix entry. For example:

Carry out pouring:
	let C be the color of the noun;
	let B be the color of BowlPaint;
	repeat through the Table of Mixing:
		if the previous entry is B and the new entry is C, now BowlPaint is the resulting mix entry;
		if the previous entry is C and the new entry is B, now BowlPaint is the resulting mix entry; [checking reversed means fewer rows in the table]
4 Likes

I would make a bunch of phrases, one for each interesting color, and one more phrase to use them to do the complete mixing operation. (And pouring can jut then use that mixing phrase.)

To decide what color is (C - a color) muddled (this is muddling): decide on brown.
To decide what color is (C - a color) combined with red (this is combining with red):
  if C is:
    otherwise -- decide on brown.
[Define a separate phrase for each specific color to be combined with, except white and brown.  Use brown as the default for everything else, and skip white.]
To decide what color is (C1 - a color) mixed with (C2 - a color):
  if C1 is equal to C2, decide on C1;
  if C1 is white, decide on C2;
  if C2 is white, decide on C1;
  let combination be muddling;
  if C1 is:
    red -- now combination is combining with red;
    blue -- now combination is combining with blue;
    [Add entries for other colors, except white and brown.]
  decide on combination applied to C2.

(I haven’t tested this code and you may need to fix some syntax errors.)

Or you can just do the same thing without the extra phrase definitions:

To decide what color is (C1 - a color) mixed with (C2 - a color):
  if C1 is equal to C2, decide on C1;
  if C1 is white, decide on C2;
  if C2 is white, decide on C1;
  let combination be muddling;
  if C1 is:
    red --
      if C2 is:
        blue -- decide on purple;
        yellow -- decide on orange;
        orange -- decide on red;
    blue --
      if C2 is:
        red -- decide on purple;
        yellow -- decide on green;
        purple -- decide on blue;
    [Add entries for other colors, except white and brown.]
    purple --
      if C2 is:
        ...whatever...
  decide on brown.

But as you do this, you’ll probably notice that you’re repeating yourself: blue mixed with yellow is the same as yellow mixed with blue. After checking for equal colors, you could do

  if C2 is less than C1:
    let T be C1;
    now C1 is C2;
    now C2 is T;

and then skip any entries when C2 comes before C1.

4 Likes

Thanks. I kind of figured this kind of table wouldn’t work but it would’ve made a few things I’m thinking about easier for me to visualize if it did. Thanks for the pointers.

1 Like

It can be made to work, but it’s not a tidy one-line solution. It would be a bit messy, like the other examples in this thread.

1 Like

I have an elegant proof for this algorithm. Alas, the margins of this reply are too small to contain it.

a color is kind of value.
red, blue, yellow, green, orange, purple, brown, white are colors.
To decide what number is the numerical value of (c - color): (- {c} -).

To decide what color is (c1 - color) mixed with (c2 - color):
 if c1 is c2, decide on c1;
  if c2 > c1 begin;
    let c0 be c2;
    now c2 is c1;
    now c1 is c0;
  end if;
  if c1 is white, decide on c2;
  if c1 is brown, decide on brown;
  let x1 be the numerical value of c1;
  let x2 be the numerical value of c2;
  if ((x1 + x2) > 8) or (x1 is 4 and x2 is 1) or (x1 is 5 and x2 is 2), decide on brown;
  if x2 is 3, decide on yellow;
  if x1 is 3 and x2 is 2, decide on green;
  if x2 is 2, decide on blue;
  if x1 is 2, decide on purple;
  if x1 is 3, decide on orange;
  decide on red;

To say (n - number) spaces: (- PrintSpaces({n}); -).
To say (sv - sayable value) spaced8:
  let x be the substituted form of "[sv]";
  say "[x][(8 - (number of characters in x)) spaces]";
  
when play begins:
say "" spaced8;
repeat with c0 running from red to white begin; [cols]
say "[c0]" spaced8;
end repeat;
say line break;
repeat with c1 running from red to white begin; [rows]
say "[c1]" spaced8;
repeat with c2 running from red to white begin; [cols]
say "[c2 mixed with c1]" spaced8;
end repeat;
say line break;
end repeat;

Lab is a room.

(I assumed white mixed with brown was supposed to end up brown, not white.)

[ Edited:ah, shucks, didn’t read the whole thread and @sadiedemight already posted all the parts of this approach that had any merit… ]

3 Likes

The code I posted was just a test program I made to see if I could get this style of table to work/practice with using a table. I think going forward I’ll need to use otistdog’s solution just because it’s the one I most understand and can replicate for other tables I’ll make.

But I appreciate everybody’s help. (Yes, I am reading 50 Years of Text Games which is what made me pick Inform7 back up again after my time away)

2 Likes