(move:) macro does not remove value after copying it.

0 votes
asked Nov 24, 2017 by Derasght (160 points)

I have created an array, containing every possible character to choose from (8, to be specific), however when I needed to discard one random character from the list before presenting a choice for the player, I encountered this problem. I created an empty array $chardiscard and tried to move one of the characters there, however, all 8 of them stayed in the original array. This is the code I used to set up the array:

(set: $chardeck to (a: "Character 1", "Character 2", "Character 3", "Character 4", "Character 5", "Character 6", "Character 7", "Character 8"))

And this is me trying to move it:

{(set: $chardiscard to (a: ))
(move: (either: ...$chardeck) into $chardiscard)}

$chardiscard succesfully received variable, yet it also stayed in the original array. Where is my mistake?..

The only way I could resolve that problem was by using (random:) and checking each possibility...

{(set: $chardiscard to (a: ))
(set: _random to (random: (1,8)))
(if: _random is 1)[(move: $chardeck's 1st into $chardiscard)]
(if: _random is 2)[(move: $chardeck's 2nd into $chardiscard)]
(if: _random is 3)[(move: $chardeck's 3rd into $chardiscard)]
(if: _random is 4)[(move: $chardeck's 4th into $chardiscard)]
(if: _random is 5)[(move: $chardeck's 5th into $chardiscard)]
(if: _random is 6)[(move: $chardeck's 6th into $chardiscard)]
(if: _random is 7)[(move: $chardeck's 7th into $chardiscard)]
(if: _random is 8)[(move: $chardeck's 8th into $chardiscard)]}

But when the amount of values will be much greater (and it will), this code will become too cumbersome. Is there a more elegant solution?

1 Answer

+1 vote
answered Nov 24, 2017 by Chapel (51,550 points)
selected Nov 24, 2017 by Derasght
Best answer

The problem is that you aren't removing from the array, you're removing from the result of the (either:) expression. The original array is never touched. Use a random number instead: 

(set: _idx to (random: 1, 8))
(move: $chardeck's (_idx) into $chardiscard)

Since $chardiscard is an array, you'll probably not want to do it that way though, since you're not specifying an index, meaning the moved value is replacing the whole array data structure. Here's a workaround: 

(set: _idx to (random: 1, 8))
(move: $chardeck's (_idx) into _char)
(set: $chardiscard to it + (a: _char))

You can also just specify the appropriate index, if that's possible for you. Note that you could instead just do this all with a single (set:), though it is a little harder to read: 

(set: _char to (either: ...$chardeck), $chardeck to it - (a: _char), $chardiscard to it + (a: _char))


Welcome to Twine Q&A, where you can ask questions and receive answers from other members of the community.

You can also find hints and information on Twine on the official wiki and the old forums archive.

See a spam question? Flag it instead of downvoting. A question flagged enough times will automatically be hidden while moderators review it.