0 votes
asked by (140 points)

Hello. I am looking to have a batch of options that are chosen randomly by the program when a player accesses a passage, but then have the randomly chosen outcome removed from the list of possibilities. That way, the next time the player generates another random number, it can't be chosen again.

Basically:

Passage 1: The random number is selected by the game. The player has the option to accept the option (go forward with it), or ignore it (return to a previous screen via a link).

If the player accepts the option: the option should be removed from the pool of possible random choices, so the next time they randomly roll a passage, it cannot be selected.

Here is the basic code I have right now, using just the random: macro. I now have the idea to change my plan to be able to do each option only once (after accepting to take it), so I know it needs to change but I'm not sure how. Thanks fo any help.

(set: $choice to (random: 1, 3))
(if: $choice is 1)[Here is where the content of the choice is, including the link to the next passage.

[[Link to Accept]]
[[Link to Ignore]]
]

(elseif: $choice is 2)[Here is where the content of the choice is, including the link to the next passage.

[[Link to Accept]]
[[Link to Ignore]]
]

(elseif: $choice is 3)[Here is where the content of the choice is, including the link to the next passage.


[[Link to Accept]]
[[Link to Ignore]]
]

1 Answer

0 votes
answered by (520 points)

Instead using (random:), I would suggest making a more easily manipulated array. I believe this will do what you want.

(set: $random to (a: 1, 2, 3))
(set: $choice to (either: ...$random))

(if: $choice is 1)[Here is where the content of the choice is, including the link to the next passage.

(link: "Link to Accept")[(goto: "Next passage")(set: $random to it - 1)]
[[Link to Ignore]]
]

(elseif: $choice is 2)[Here is where the content of the choice is, including the link to the next passage.

(link: "Link to Accept")[(goto: "Next passage")(set: $random to it - 2)]
[[Link to Ignore]]
]

(elseif: $choice is 3)[Here is where the content of the choice is, including the link to the next passage.

(link: "Link to Accept")[(goto: "Next passage")(set: $random to it - 3)]
[[Link to Ignore]]
]

Note how a number is removed from the array, making it so the choice can't be repeated.

commented by (125k points)

Two small correction to and a couple of suggests for @Piply's great answer:

1. The $random Array needs to be initialised before the above "Show Random Choices" passage, otherwise the story won't remember which choices have already been seen. One possible place to do this initialisation is within your project's startup tagged special passage.

(set: $random to (a: 1, 2, 3))

... there is a related issue which is what happens if the Reader visits the "Show Random Choices" passage after all the possible random choices have been seen. (eg. the $random Array is empty!)

There are two basic ways to handle this situation:
a. Structure the story so that the Reader can't revisit the passage once all the random choices have been seen.
b. Add a check of the $random's length to the passage and react accordingly when it's empty.

(if: $random's length is 0)[
	<!-- What to do when there are no more choices left in the Array? -->
	There are no more choices left!
]


2. The correct syntax for deleting an item from an Array is

(set: $random to it - (a: 1))


3. Generally when using a combination of the (link:) macro and the (goto:) macro to create a link that forwards to another Passage when selected the (goto:) macro should be called last in the (link:) macro's associated hook.

(link: "Link to Accept")[
	(set: $random to it - (a: 1))
	(goto: "Next passage")
]


4. Combining Collapsing whitespace markup with the HTML br (line-break) element can help when tying to remove unwanted blank lines from the text being displayed on the page, especialy if that text is the result of conditional logic. It helps when trying to format your Passage content so it's a little easier to read within the Passage Editor.

The following is a corrected and slightly changed version of  @Piply's example.

{
(if: $random's length is 0)[
	<!-- What to do when there are no more choices left in the Array? -->
	There are no more choices left!
]
(else:)[

(set: $choice to (either: ...$random))

(if: $choice is 1)[
Here is where the content of choice 1 is, including the link to the next passage.
<br><br>
(link: "Link to Accept")[
	(set: $random to it - (a: 1))
	(goto: "Next passage")
]
<br>
[[Link to Ignore]]
]

(elseif: $choice is 2)[\
Here is where the content of choice 2 is, including the link to the next passage.
<br><br>
(link: "Link to Accept")[
	(set: $random to it - (a: 2))
	(goto: "Next passage")
]
<br>
[[Link to Ignore]]
]

(elseif: $choice is 3)[\
Here is where the content of choice 3 is, including the link to the next passage.
<br><br>
(link: "Link to Accept")[
	(set: $random to it - (a: 3))
	(goto: "Next passage")
]
<br>
[[Link to Ignore]]
]

]
}

 

commented by (520 points)
Thank you for the corrections. I'll definitely be reevaluating my own work with your points in mind.
commented ago by (140 points)
Thank you both for your input. I will try that out!
...