Accessing a list of a single property of multiple things

image

1 Like

I’d be in there with bitwise operations (1=red, 2=green, 4=blue…) but that’s me.

1 Like

Inspired by @zarf, I came up with this. Not perfect (the secondary colors dominate when mixed with any primary, for example) but you get the idea.

Lab is room.
A color is a kind of value.
white, blue, yellow, green, red, violet, orange, and brown are colors.

To decide what color is (c1 - a color) mixed with (c2 - a color):
	(- (({c1}-1) | ({c2}-1) + 1); -).

When play begins:
	repeat with first running through colors:
		repeat with second running through colors:
			say "[first] mixed with [second] is [first mixed with second].".

2 Likes

I tried to use relations at one point but couldn’t figure out how to make it work (still fairly new to this language and struggling through learning its various features).

@zarf’s bitwise idea feels like the most elegant solution here

1 Like

This is perhaps the most convoluted use of relations I’ve ever seen. Even experienced Inform users generally don’t know that it’s possible! So don’t worry about that part.

2 Likes

Yeah, what Daniel said. My code would compile but not work in 9.3/6M62. To my knowledge, relations as properties don’t work at all before 10.1, and in 10.1’s two years now of existence, I don’t think I’ve seen anyone else use them.

That said, Graham’s 2020 talk at Narrascope put forth:

Inform’s “Everything is an X”: relations and rules
[…]
For Inform, there are two big ideas: relations and rules.

I think it’s the case that something like my solution is actually “meant to” be the Inform-ish approach to a problem like this (or, at very least, that there’s a defensible argument for such).

Unfortunately, the docs are so opaque and omit so much detail you need to actually have a shot of knowing what’s possible and how to express that in code, that relations’ use tends toward the simplistic.

2 Likes

And I always find myself wishing there could be more overlap between them…

1 Like

Just to cross-reference an additional resource, here’s a straightforward table-based approach by @otistdog: Table with identical columns and rows - #2 by otistdog.

1 Like

This is a valid way to do it, I guess it just feels… inelegant? Like, color mixing should be commutative (you shouldn’t have to account for both “red and blue” and “blue and red”). That said, a table approach would probably be the most flexible in terms of things like where one of these glowing chameleon things in my game is in its “off” cycle” but the other one is red (thus the room’s color would be a “dim red.”)

At a certain point one might as well just use RGB hex values to accomplish all of this, and maybe I’ll think about that as an extension idea one day when I’m more familiar with Inform 7.

Yeah maybe just implement this CSS/Properties/color/keywords - W3C Wiki

Well, enumerated values can be sorted, so you can deal with commutativity that way—just put the smaller one first before doing any lookups!

In the given example the “Carry out” rule checks for both orders, so that you don’t have to duplicate the rows in the table.

1 Like

This has the flexibility a rulebook offers, but counts on the author stating the rules with the colors in ascending order.

lab is a room.

color is a kind of value.

the colors are brown, red, orange, yellow, blue, green, indigo, violet.

color-mix is a list of colors that varies.

blending is a rulebook producing a color.

blending when color-mix is { red, blue }: rule succeeds with result violet.

last blending: rule succeeds with result brown.

to decide what color is (c1 - color) mixed with (c2 - color):
  if c1 is c2, decide on c1;
  truncate color-mix to 0 entries;
  add c2 to color-mix;
  if c1 < c2, add c1 at entry 1 in color-mix;
  else add c1 to color-mix;
  decide on the color produced by blending;

when play begins:
  say "red + blue = [red mixed with blue].";
  say "blue + red = [blue mixed with red].";
  say "orange + green = [orange mixed with green].";

Hat tip to @OtisTDog, who showed me this trick when I was a noob.

Since 10.1, the compiler seems to accept a list of colors based rulebook with no reservations, so I’d say it would be more idiomatic to utilize that feature and eliminate an evil global. (It’s only a minor detail, though.)

Modification (which does not compile with 6M62)
lab is a room.

color is a kind of value.

the colors are brown, red, orange, yellow, blue, green, indigo, violet.

blending is a list of colors based rulebook producing a color.

blending { red, blue }: rule succeeds with result violet.

last blending: rule succeeds with result brown.

to decide what color is (c1 - color) mixed with (c2 - color):
  let color-mix be a list of colors;
  if c1 is c2, decide on c1;
  add c2 to color-mix;
  if c1 < c2, add c1 at entry 1 in color-mix;
  else add c1 to color-mix;
  decide on the color produced by blending for color-mix;

when play begins:
  say "red + blue = [red mixed with blue].";
  say "blue + red = [blue mixed with red].";
  say "orange + green = [orange mixed with green].";
1 Like

Nice!

Zounds! Beat me to it :laughing:

Actually, this compiles and works when using Z-machine in 6M62.

I see with 6M62 Glulxe throws a memory error- any idea why?

This attaches to each color value (as a property called mixmaster), what Inform calls a various to various relation, which is essentially a binary matrix (Boolean matrix, logical matrix), initially populated with all zeros, with x and y indices made up of all the possible colour values:

    B R O Y B G I V
  B 0 0 0 0 0 0 0 0
  R 0 0 0 0 0 0 0 0
  O 0 0 0 0 0 0 0 0
  Y 0 0 0 0 0 0 0 0
  B 0 0 0 0 0 0 0 0
  G 0 0 0 0 0 0 0 0
  I 0 0 0 0 0 0 0 0
  V 0 0 0 0 0 0 0 0

To see if in the mixmaster property of the color blue, yellow relates to green, you’d find the yellow column then cross-reference that with the green row: if the value at the intersection is a 0, it does not so relate, if a 1 it does relate, (the implication for our purposes being that blue + yellow gives green):

As after:

blue mixed with yellow is green;
mixmaster of the color blue:
    B R O Y B G I V
  B 0 0 0 0 0 0 0 0
  R 0 0 0 0 0 0 0 0
  O 0 0 0 0 0 0 0 0
  Y 0 0 0 0 0 0 0 0
  B 0 0 0 0 0 0 0 0
  G 0 0 0 1 0 0 0 0
  I 0 0 0 0 0 0 0 0
  V 0 0 0 0 0 0 0 0

It will immediately be obvious that we could in theory set up or end up ‘corrupting’ the matrix so:

blue mixed with yellow is orange;
blue mixed with yellow is violet;
blue mixed with yellow is green;

after which

mixmaster of the color blue	
    B R O Y B G I V
  B 0 0 0 0 0 0 0 0
  R 0 0 0 0 0 0 0 0
  O 0 0 0 1 0 0 0 0
  Y 0 0 0 0 0 0 0 0
  B 0 0 0 0 0 0 0 0
  G 0 0 0 1 0 0 0 0
  I 0 0 0 0 0 0 0 0
  V 0 0 0 1 0 0 0 0

in which case blue + yellow gives green, but could equally give orange or violet. Sometimes its useful for something to relate to more than one other thing, but in the current context mixing two colours can only produce one possible result, so we want to be sure that one- but no more than one- 1 appears in each column of the matrix, corresponding to the color produced by mixing the color holding that mixmaster property with the color of the column heading.

So-

to (c1 - color) mixed with (c2 - color) is (c3 - color):
[first clear out any existing relations in the relevant columns (i.e. set the columns all to 0), so we can't end up with more than one 1 in a column]
	repeat with c running through colors:
		now the mixmaster of c1 does not relate c2 to c;
		now the mixmaster of c2 does not relate c1 to c;
[now make the relations, ensuring reciprocity, so that e.g. blue + red gives the same color as red + blue- by adjusting the mixmasters of both red and blue simultaneously so red has one 1 in column blue and row violet, and blue has one 1 in column red and row violet.]
	now the mixmaster of c1 relates c2 to c3;
	now the mixmaster of c2 relates c1 to c3;

Now after

blue mixed with yellow is orange;
blue mixed with yellow is violet;
blue mixed with yellow is green;
mixmaster of the color blue	
    B R O Y B G I V
  B 0 0 0 0 0 0 0 0
  R 0 0 0 0 0 0 0 0
  O 0 0 0 0 0 0 0 0
  Y 0 0 0 0 0 0 0 0
  B 0 0 0 0 0 0 0 0
  G 0 0 0 1 0 0 0 0
  I 0 0 0 0 0 0 0 0
  V 0 0 0 0 0 0 0 0

the first two phrases are each overridden in turn and, in the end, blue + yellow only gives green

1 Like

I’m not sure @Zed if it’s possible (or indeed useful) to set up other kinds of relation as properties- they could presumably be implemented as ‘list of x’ properties etc.? That said, the colour-mixing scenario could also I suppose be implemented as 2 ‘list of colours’ properties forming a hash table. (meaning that, to find out what mixing blue and yellow gives, look-up yellow in blue’s ‘look-up-list-property’ {brown, red, orange, yellow, blue, green, indigo, violet} i.e. entry 4, then read off the corresponding 4th entry in the 'results-list-property` {brown, violet, brown, green, blue, green, indigo, violet}).

1 Like