0 votes
by (190 points)

Using Sugarcube 2-28 and Twine 2.31

So, after the player does a quiz with eleven questions, I want whichever animal has the greatest number amongst the four to be the one that gets set to the variable 'familiar'. It worked like I wanted it to for two tries before proving that my below code is not actually working. When testing, it began to give me a variable that wasn't even near the greatest of the four (i.e wisp is 4 and phoenix is 9 but familiar becomes set to wisp). Can someone give me some insight about what I'm doing wrong with it?

<<if $cockatrice gt ($phoenix) and ($wisp) and ($blackdog)>>\
	<<set $familiar to "cockatrice">>
<</if>>\
<<if $phoenix gt ($cockatrice) and ($wisp) and ($blackdog)>>\
	<<set $familiar to "phoenix">>
<</if>>\
<<if $blackdog gt ($cockatrice) and ($wisp) and ($phoenix)>>\
	<<set $familiar to "blackdog">>
<</if>>\
<<if $wisp gt ($cockatrice) and ($blackdog) and ($phoenix)>>\
	<<set $familiar to "wisp">>
<</if>>\

 

1 Answer

+1 vote
by (159k points)

When evaluating a conditional expression that is made up of multiple sub-expressions you need to include the variable being referenced in each of those sub-expressions. So the first <<if>> macro in your example should look somthing like the following (untested) code.

<<if $cockatrice gt $phoenix and $cockatrice gt $wisp and $cockatrice gt $blackdog>>\
	<<set $familiar to "cockatrice">>
<</if>>\


Each of your multiple <<if>> macros is assigning a value to the same $familiar variable, this means that the conditional expressions of those set of <<if>> macros are whats known as mutually exclusive. When you have such a situation the 2nd and later <<if>> macros should actually be <<elseif>> macros.

<<if $cockatrice gt $phoenix and $cockatrice gt $wisp and $cockatrice gt $blackdog>>
	<<set $familiar to "cockatrice">>

<<elseif $phoenix gt $cockatrice and $phoenix gt $wisp and $phoenix gt $blackdog>>
	<<set $familiar to "phoenix">>

<<elseif $blackdog gt $cockatrice and $blackdog gt $wisp and $blackdog gt $phoenix>>
	<<set $familiar to "blackdog">>

<<elseif $wisp gt $cockatrice and $wisp gt $blackdog and $wisp gt $phoenix>>
	<<set $familiar to "wisp">>
<</if>>


Your set of <<if>> related macro calls produce no visible output other than the line-breaks being used to format the code, which you are currently using Line Continuation markup to suppress. Using that method in this type of situation can be a chore so I suggest using either: the <<nobr>> macro to suppress all those line-breaks; or the <<silently>> macro to suppress all possible visible output; instead.

In this specific case I think the 2nd option is the better choice as it also supresses the characters being used for indentation.

<<nobr>>
	<<if $cockatrice gt $phoenix and $cockatrice gt $wisp and $cockatrice gt $blackdog>>
		<<set $familiar to "cockatrice">>

	<<elseif $phoenix gt $cockatrice and $phoenix gt $wisp and $phoenix gt $blackdog>>
		<<set $familiar to "phoenix">>

	<<elseif $blackdog gt $cockatrice and $blackdog gt $wisp and $blackdog gt $phoenix>>
		<<set $familiar to "blackdog">>
		
	<<elseif $wisp gt $cockatrice and $wisp gt $blackdog and $wisp gt $phoenix>>
		<<set $familiar to "wisp">>
	<</if>>
<</nobr>>

<<silently>>
	<<if $cockatrice gt $phoenix and $cockatrice gt $wisp and $cockatrice gt $blackdog>>
		<<set $familiar to "cockatrice">>

	<<elseif $phoenix gt $cockatrice and $phoenix gt $wisp and $phoenix gt $blackdog>>
		<<set $familiar to "phoenix">>

	<<elseif $blackdog gt $cockatrice and $blackdog gt $wisp and $blackdog gt $phoenix>>
		<<set $familiar to "blackdog">>

	<<elseif $wisp gt $cockatrice and $wisp gt $blackdog and $wisp gt $phoenix>>
		<<set $familiar to "wisp">>
	<</if>>
<</silently>>


There is one more potential issue with your example, it doesn't consider the case when the all four variables equal the same value, in which case none of the above conditional expressions would evaluate to true which would result in the $familiar variable not being assigned a value.

Two simple ways to get arround this issue are:

a. Assign a default value to the $familiar sometime before the above code gets evaluated, a good place to do such initialisatation is within your project's StoryInit special passage.

<<set $familiar to "some default value">>

b. Add an <<else>> macro call to the end of your set of <<if>> related macros to handle any situation not already handled by the other conditional expressions.

<<silently>>
	<<if $cockatrice gt $phoenix and $cockatrice gt $wisp and $cockatrice gt $blackdog>>
		<<set $familiar to "cockatrice">>

	<<elseif $phoenix gt $cockatrice and $phoenix gt $wisp and $phoenix gt $blackdog>>
		<<set $familiar to "phoenix">>

	<<elseif $blackdog gt $cockatrice and $blackdog gt $wisp and $blackdog gt $phoenix>>
		<<set $familiar to "blackdog">>

	<<elseif $wisp gt $cockatrice and $wisp gt $blackdog and $wisp gt $phoenix>>
		<<set $familiar to "wisp">>

	<<else>>
		<<set $familiar to "some default value">>
	<</if>>
<</silently>>

 

by (190 points)
Thank you so much, works flawlessly!
...