Personality Quiz Help

Twine Version: Twine 2.0
Story Format: Sugarcube 2

Near the beginning of my game, I want to create somewhat of a personality quiz as part of the character creation. I know how to change variables depending on which option is picked, and how to show different text depending on which variable is the highest. My question is, what if two variables are tied for the highest? How do I get the program to

  1. Detect if two or more variables out of a set are equal and
  2. Pick a random variable out of those equal variables.
    Here’s an example of how I detect which variable is highest in the case that there are no equal variables:

<<switch Math.max($redPercent, $bluePercent, $yellowPercent)>>
<<case $redPercent>>
You are red
<<case $bluePercent>>
You are blue
<<case $yellowPercent>>
You are yellow
<>

If you’re working with a bunch of values, then it’s best to make them all part of either the same array or the same generic object. That makes dealing with all of them much easier.

For example, instead of having three variables, $redPercent, $bluePercent, and $yellowPercent, it might make more sense to have one $percent variable as a generic object which has .red, .blue, and .yellow properties. You might initialize that object like this:

<<set $percent = { red: 0, blue: 0, yellow: 0 }>>

Note: If any property names either start with a number or include any non-alphanumeric characters other than “_” and “$”, then the property name would have to be within quotes when used like that. For example, let’s add the color “burnt sienna”:

<<set $percent = { red: 0, blue: 0, yellow: 0, "burnt sienna": 0 }>>

You could then access any of the properties on that $percent object by doing something like this:

<<set $percent.red += 5>>  /* Adds 5 to the current "red" property value. */

Note: Property names that start with a number or include any non-alphanumeric characters other than “_” and “$” are different again, in that, instead of using “dot notation” like the above, you’d have to use “bracket notation” like this:

<<set $percent["burnt sienna"] += 3>>  /* Adds 3 to the current "burnt sienna" property value. */

Now that we have all of those values grouped together onto a single $percent object variable, we can use a loop to randomly pick one of the highest values on that object:

<<silently>>
	<<set _color = Object.keys($percent).shuffle()>>  /* Gets a randomly sorted array of all property names on the object. */
	<<set _topColor = _color[0]>>  /* Starts with the first color. */
	<<for _i = 1; _i < _color.length; _i++>>  /* Looks for any colors with a higher value. */
		<<if $percent[_color[_i]] > $percent[_topColor]>>
			<<set _topColor = _color[_i]>>  /* Found a new highest value. */
		<</if>>
	<</for>>
<</silently>>You are _topColor.

That will either give you the top scoring color or, if more than one property is tied for the top score, it randomly gives you the name of one of those highest scoring colors. That code will work for any number of property names as well. (See the JavaScript Object.keys() method for details on how that works.)

Please let me know if you have any questions on any of that.

Enjoy! :grinning: